Mohlo by vás zajímat

Obecné informace

Složky a soubory

Složky

  • /css — vývojové soubory stylů.
  • /css/components — vývojové soubory stylů pro jednotlivé komponenty.
  • /js — vývojové soubory skriptů.
  • /js/modules — vývojové soubory skriptů pro jednotlivé komponenty/moduly.
  • /libs — vývojové soubory použitých knihoven a pluginů.
  • /img — soubory použitých obrázků.
  • /img/src — zdrojové soubory použitých obrázků, které se mají použít pro optimalizaci (Viz .)
  • /img/svg-sprite — soubory týkající se SVG spritu (soubor obsahující více SVG souborů; SVG ikony). (Viz .)
  • /img/svg-sprite/src — zdrojové soubory pro vytvoření SVG spritu. (Viz .)
  • /img/svg-sprite/symbol/svgSVG sprite založený na symbolech. (Viz .)
  • /img/svg-sprite/view/svgSVG sprite založený na view. (Viz .)
  • /fonts — soubory použitých písem.
  • /favicon — soubory pro favicon.
  • /build — spojené a minifikované soubory stylů a skriptů.
  • /dev — soubory potřebné pro vývoj šablony. (Viz .)
  • /dev/templates — soubory se šablonami pro generovaný kód. (Viz .)
  • /dev/templates/data — soubory s daty pro šablony pro generovaný kód. (Viz .)
  • /dev/ie11CustomProperties — knihovna, která přidává podporu pro CSS Custom Propertíes do IE 11. (Viz GitHub.)
  • /manual — tento manuál.

Komponenty, které jsou rozdělené na více souborů, mají vlastní složku, jejíž název odpovídá názvu komponentu. Má-li nějaký komponent rozšířené varianty, pak budou většinou společně ve složce s názvem základního komponentu (například: komponent page a jeho rozšířená varianta home-page budou ve složce /css/components/page).

Soubory

  • /README.md — základní vysvětlení vytvoření produkčního kódu.
  • /build/all.build.css — spojené styly (včetně knihoven a pluginů, které nejsou načítané z CDN).
  • /build/all.build.min.css — spojené a minifikované styly (včetně knihoven a pluginů, které nejsou načítané z CDN).
  • /build/print.build.css — spojené tiskové styly.
  • /build/print.build.min.css — spojené a minifikované tiskové styly.
  • /build/all.build.js — spojené skripty (včetně knihoven a pluginů, které nejsou načítané z CDN).
  • /build/all.build.min.js — spojené a minifikované skripty (včetně knihoven a pluginů, které nejsou načítané z CDN).
  • /js/init.js — soubor inicializující jednotlivé JS moduly.
  • /js/GNS.js — soubor (modul) s globálním jmenným prostorem a sdílenými vlastnostmi (properties) pro JS. (Viz )
  • /css/reset.css — soubor resetující výchozí styly prohlížeče.
  • /css/main.css — soubor se základními styly obsahu webu. (Viz .)
  • /css/utility.css — soubor s pomocnými styly. (Viz .)
  • /css/custom-properties.css — základní nastevení globálních proměnných. (Viz .)
  • /css/print.css — soubor se základními tiskovými styly.
  • /img/svg-sprite/symbol/svg/sprite.symbol.svgSVG sprite založený na symbolech. (Viz .)
  • /img/svg-sprite/view/svg/sprite.view.svgSVG sprite založený na view.
  • /dev/PATHS.js — nastavení cest ke složkám a souborům. (Viz , a .)
  • /dev/load-js.js — načítá (pouze pro účely vývoje) a spojuje soubory skriptů. (Viz a .)
  • /dev/load-css.js — načítá (pouze pro účely vývoje) a spojuje soubory stylů. (Viz a .)
  • /dev/cssimport/all.build.css — načítá soubory stylů při vypnutém JS (pouze pro vývoj šablony). (Viz a .)
  • /dev/cssimport/print.build.css — načítá tiskové styly při vypnutém JS (pouze pro vývoj šablony). (Viz a .)
  • /gulpfile.js — soubor s automatizačními skripty pro Gulp.
  • /package.json — soubor s nastavením NPM.
  • /.babelrc — soubor s nastavením pro Babel (kompilace ES2015+ do ES5).

HTML kód jednotlivých stránek se nachází v kořenovém adresáři.

Některé složky a soubory nemusí existovat, nejsou-li pro projekt relevantní.

Vývoj šablony

Pro upravování kódu (s vyjímkou HTML) je potřeba mít nainstalovaný Node.js a NPM a nainstalovat potřebné moduly následujícím příkazem:

                                
                                    npm install
                                
                            

K dispozici je pak gulp-task watch, který automaticky spojí a zkompiluje soubory, pokud se nějaký změní (nebo pokud se změní /dev/load-css.js nebo /dev/load-js.js):

                                
                                    npm run gulp watch
                                
                            

Toto platí pouze pro gulp-tasky css a js. Optimalizace obrázků nebo vytváření SVG spritu, je potřeba vždy spustit manuálně.

Gulp-taskem build je pak možné spojit a zkompilovat styly a skripty a odkomentovat potřebné elementy v HTML souborech.

Pro detaily o spojování a kompilaci CSS a JS viz a , pro detaily o práci s vývojovými a produkčními soubory v HTML viz a .

HTML soubory

HTML soubory jsou rozdělené do několika sekcí, které jsou označené komentáři typu <!--———————————— SECTION ————————————-->.

Styly jsou vložené v elementu head v sekci <!--— STYLES —--> a skripty na konci elementu body v sekci <!--— JAVASCRIPT —-->. Soubory pro produkční verzi jsou označené komentáři <!--prod--> a <!--/prod--> a pro vývoj <!--dev--> a <!--/dev-->. Vložené soubory pro produkční verzi jsou zpravidla minifikované.

Kód CSS a JS upravujte vždy v nespojených (tedy ve vývojových) souborech, tzn. ve složkách /css a /js. Upravený kód je pak potřeba spojit pomocí příslušného gulp-tasku. Více viz a .

Některé další sekce v HTML dokumentech:

  • <!--— META-GENERAL —--> — obecná metadata (nastavení znakové sady, …).
  • <!--— META-PAGE —--> — metadata o stránce (description, …) včetně elementu title.
  • <!--— PRELOAD —--> — kód pro přednačtení potřebných souborů a pro předspojení s dalšími servery.
  • <!--— FAVICON —--> — kód pro vytvoření favicon.
  • <!--— META-SHARE —--> — kód s metadaty pro sociální sítě apod.
  • <!--— FONTS —--> — kód pro načtení písem.
  • <!--— SUPPORT —--> — kód pro zajištění podpory pro starší prohlížeče.
  • <!--— CONTENT —--> — obsah stránky.
  • <!--— APPENDED —--> — kód přidaný po načtení stránky.

HTML kód pro vývoj

V HTML souborech jsou vložené soubory pro vývoj šablony, které jsou zakomentované a ohraničené komentáři <!--dev--> a <!--/dev-->. Tento kód je tedy možné pro produkční verzi odstranit. Jedná se (zejména) o soubory /dev/load-js.js, /dev/load-css.js, /dev/PATHS.js a /dev/cssimport/all.build.css. Skripty vkládají vývojové soubory CSS a JS do stránky. Při vývoji tento kód používat nemusíte. Tyto soubory se ale také používají pro spojování a kompilaci CSS a JS.

V sekci <!--— STYLES —--> se v IE 11 vkládá soubor dev/ie11CustomProperties/ie11CustomProperties.js, který zajišťuje podporu CSS Custom Properties. (Pro produkci se nepoužívá, protože proměnné se nakonec nepoužijí a zkompilují se pomocí PostCSS.)

V sekci <!--— JAVASCRIPT —--> se v IE 11 vkládají soubory pro kompilaci ES2015+ do ES5. (Pro produkci se kód zkompiluje.)

V souboru /dev/PATHS.js lze nastavit cesty k souborům. (Popis jednotlivých vlastností je uvnitř souboru a v relevantních sekcích.)

Proces práce s vývojovými soubory je optimalizovaný pro použití editoru Brackets a jeho funkci Live Preview, kde je potřeba vložit do stránky vývojové soubory a ne pouze soubory spojené.

Pomocí výše zmíněných skriptů vložíte do stránky soubory přesně tak, jako by byly spojené (pouze spojené bez dalších modifikací). Jak se další soubory přidávají, naleznete v následujích sekcích a .

Pokud se používají jiná spojení pro každou stránku (nebo více souborů), je potřeba zadat název spojeného souboru do atributu data-file (viz Příklad 1). Pokud se používá více souborů, oddělují se čárkou (,). V případě stylů je také možné přidat atribut data-media, podle kterého se nastaví atribut media u elementů link (počet a pořadí musí odpovídat počtu a pořadí souborů).

Pro CSS je také ve složce /dev/cssimport soubor se stejným názvem jako má soubor spojený, ale je založený na načítání souborů pomocí @import. Tento soubor slouží pro testování s vypnutým JS. (Tento soubor je potřeba vytvořit gulp-taskem css.)

Používáme dvě různé varianty JS a CSS souborů. V souborech /dev/load-js.js a /dev/load-css.js tak máme v objektech FILES následujicí kód:

                                    
                                    /*/dev/load-js.js*/
                                    var FILES = {
                                        "homepage.build.js": [
                                            "js/modules/Homepage.js",
                                            "js/homepage-init.js"
                                        ],

                                        "subpage.build.js": [
                                            "js/modules/Subpage.js",
                                            "js/subpage-init.js"
                                        ]
                                    };

                                    /*/dev/load-css.js*/
                                    var FILES = {
                                        "homepage.build.css": [
                                            "css/reset.css",
                                            "css/components/homepage.css"
                                        ],

                                        "subpage.build.css": [
                                            "css/reset.css",
                                            "css/components/subpage.css"
                                        ],

                                        "print.build.css": [
                                            "css/print.css"
                                        ]
                                    };
                                    
                                

Jsme-li tedy na stránce index.html, pak musí kód vypadat takto:

                                    
                                        <!--————————— STYLES —————————-->

                                        <!--dev-->
                                        <script src="dev/PATHS.js"></script>
                                        <script src="dev/load-css.js" data-file="homepage.build.css, print.build.css" data-media="screen, print"></script>
                                        <noscript><link rel="stylesheet" href="dev/cssimport/homepage.build.css" media="screen"></noscript>
                                        <!--/dev-->


                                        <!--————————— JAVASCRIPT —————————-->

                                        <!--dev-->
                                        <script src="dev/PATHS.js"></script>
                                        <script src="dev/load-js.js" data-file="homepage.build.js"></script>
                                        <!--/dev-->
                                    
                                

A na stránce subpage.html:

                                    
                                        <!--————————— STYLES —————————-->

                                        <!--dev-->
                                        <script src="dev/PATHS.js"></script>
                                        <script src="dev/load-css.js" data-file="subpage.build.css, print.build.css" data-media="screen, print"></script>
                                        <noscript><link rel="stylesheet" href="dev/cssimport/subpage.build.css" media="screen"></noscript>
                                        <!--/dev-->


                                        <!--————————— JAVASCRIPT —————————-->

                                        <!--dev-->
                                        <script src="dev/PATHS.js"></script>
                                        <script src="dev/load-js.js" data-file="subpage.build.js"></script>
                                        <!--/dev-->
                                    
                                

Chcete-li použít skripty pro vkládání vývojových souborů do stránky, pak musíte zakomentovat spojené a zkompilované soubory a odkomentovat soubory vývojové. To lze udělat pomocí gulp-tasku dev. Produkční kód lze zase použít pomocí gulp-tasku prod. Gulp-tasky odkomentují/zakomentují vše mezi komentáři <!--dev--> a <!--/dev--> a <!--prod--> a <!--/prod-->.


Některé části mohou být vygenerovány pomocí šablonovacího systému nebo vloženy z jiných souborů. Jedná se zejména o kód, který se opakuje ve více souborech nebo je závislý na komplexních datech. Více informací najdete v sekci . Takovýto kód by se měl upravovat pomocí úpravy dat a příslušných šablon. Chcete-li upravovat kód rovnou ve vygenerovaném kódu, pak je vhodné odstranit komentáře definující příslušný generátor.

Úpravy HTML kódu pomocí Gulpu

Gulp-taskem edit je možné upravovat kód několika souborů najednou, pomocí modulu gulp-cheerio využívajícího knihovnu Cheerio.js, která umožňuje upravovat kód na serveru pomocí "jQuery funkcí".

Cheerio.js nijak neformátuje výsledné úpravy. Zároveň ale může rozbít formátování SVG. Proto může být vhodnější upravit kód ručně v jednom souboru a ten zkopírovat do dalších souborů gulp-taskem copy. Viz . Pokud se ale při kopírování pužívá Cheerio.js, pak stále přetrvává problém s SVG.

Základní argumenty:

  • --files, --f — soubory, které se mají upravit oddělené čárkou (výchozí *.html).
  • --run, --r — kód Cheerio.js, který se spustí pomocí eval. K dispozici je funkce $ a objekt File.
  • --dir, --d — složka se soubory. (Výchozí PATHS.HTML_INPUT.)

Potřebujeme přidat v souborech kontakt.html a clanek.html elementům .link atribut target="_blank":

                                    
                                        npm run gulp edit -- --files kontakt.html,clanek.html --run '$(".link").attr("target", "_blank")'
                                    
                                

Kopírování sekcí, komponentů a elementů pomocí Gulpu

Gulp-taskem copy je možné zkopírovat sekci, komponent nebo element z jednoho souboru do jiného.

Použití pouze na vlastní nebezpečí! Funkcionalita není důsledně ověřená a výsledek tak může být jakýkoliv. Před přepsáním se proto zkopíruje aktuální stav upravovaných souborů do složky PATHS.HTML_SAVE.

Oddělení elementů, komponentů a sekcí (prázdné řádky) nemusí vždy odpovídat požadovanému vzoru. (Konkrétně pokud se nahrazje element, který má uzavírací komentář, komponentem.)

Sekce jsou označené komentářem <!--———————————— SECTION ————————————-->.

Komponenty jsou označené komentáři <!--––––––––– ** COMPONENT ** –––––––––--><!--––––––––– // COMPONENT // –––––––––-->

V případě sekcí se zkopíruje obsah začínající komentářem až po začátek dalšího komentáře pro další sekci nebo po konečný tag head nebo body.

V případě komponentů se zkopíruje celý obsah od počátečního komentáře až po konečný komentář.

V případě elementů se zkopíruje element s celým jeho obsahem. Při vkládání před/za jiný element se zkopíruje i následující komentář (lze vypnout pomocí --x-comment).

Pro kopírování elementů se používá modul gulp-cheerio využívající knihovnu Cheerio.js.

Argumenty pro výběr sekce, komponentu nebo elementu:

  • --section, --s — název sekce, která se má zkopírovat.
  • --component, --c — název komponentu, který se má zkopírovat. (Jedná-li se o komponent rozšiřující jiný, pak se název musí dát do uvozovek a před znak | dát \.)
  • --element, --e — selektor elementu, který se má zkopírovat.
  • --replace, --r — název sekce nebo komponentu nebo selektor elementu, který se má přepsat, pokud se nepřepisuje stejná sekce, komponent nebo element jako zdrojový. (Typy musí být shodné.)
  • --replace-component, --rc — název komponentu, který se má nahradit elementem.
  • --replace-element, --re — selektor elementu, který se má nahradit komponentem.
  • --before, --b — název sekce, před kterou se má sekce vložit; název komponentu, před který se má komponent vložit; selektor elementu, před který se má element vložit.
  • --after, --a — název sekce, za kterou se má sekce vložit; název komponentu, za který se má komponent vložit; selektor elementu, za který se má element vložit.
  • --before-component, --bc — název komponentu, před který se má vložit element.
  • --after-component, --ac — název komponentu, za který se má vložit element.
  • --before-element, --be — název elementu, před který se má vložit komponent.
  • --after-element, --ae — název elementu, za který se má vložit komponent.

--section, --component a --element vybírají obsah ze zdrojového souboru, zbytek slouží pro upravované soubory a používá se pouze, pokud se nepřepisuje stejný obsah nebo pokud se vkládá další.

Ačkoliv dává smysl (například) při použití --component použít --replace-component, je potřeba použít pouze --replace. --replace-component a podobné se používají pouze, pokud se liší typy.

Argumenty pro výběr souborů:

  • --from — zdrojový soubor.
  • --to — soubory, které se mají přepsat oddělené čárkou (výchozí *.html).

Argumenty upravující nahrazování a vkládání elementů:

  • --run, --r — kód, který se spustí pomocí eval po přepsání/vložení elementu. V případě --replace jsou k dispozici proměnné (objekty Cheerio) $before (kód před změnou) a $after (kód po změně). V případě --before a --after jsou k dispozici proměnné $target (cílový element) a $inserted (vložený element).
  • --each — první nalezený element ve zdrojovém souboru nahradí první nalezený v přepisovaném souboru.
  • --x-comment, --xc — nevyhledávat uzavírací komentář (některé významné bloky HTML kódu jsou označeny komentářem). Pouze pro --before, --after, --before-component, --after-component a --replace-component.
  • --x-nl — nepřídávat volný řádek mezi vložený a cílový element. Pouze pro --before a --after.
  • --nl — přidat volný řádek na opačné straně vkládaného elementu. Pouze pro --before a --after.
  • --format, --f — stav okolního kódu, aby se správně vložily prázdné řádky. Co bude před a co za vkládaným elementem nebo komponentem. Znakem | se oddělí hodnota před a za. Možnosti: S: sekce; C: komponent; E: element. Příklad: --format "C|E" znamená: před bude komponent, za bude element. Pouze pro --replace-element, --replace-component, --before-element, --before-component, --after-element a --after-component.

Momentálně není možné vložení komponentu nebo elementu na začátek/konec jiného elementu, pokud toho nelze dosáhnout pomocí --before nebo --after.

Přidali jsme do sekce PRELOAD další link v index.html, chceme tedy sekci zkopírovat do všech ostatních souborů:

                                    
                                        npm run gulp copy -- --section preload --from index.html
                                    
                                

Nebo s explicitně vyjmenovanými soubory:

                                    
                                        npm run gulp copy -- --section preload --from index.html --to kontakt.html,clanek.html
                                    
                                

Upravili jsme v index.html komponent SOCIAL-SITES a chceme ho zkopírovat do všech ostatních souborů:

                                    
                                        npm run gulp copy -- --component social-sites --from index.html
                                    
                                

V případě, že SOCIAL-SITES rozšiřuje komponent SITES:

                                    
                                        npm run gulp copy -- --component "social-sites \| sites" --from index.html
                                    
                                

Upravili jsme v index.html elementy .main-nav__link tím, že jsme jejich obsah obalili do elementu span.text:

                                    
                                        <!-- před úpravou: -->

                                        <ul class="main-nav__items">
                                            <li class="main-nav__item">
                                                <a class="main-nav__link main-nav__link--active" href="index.html">Úvod</a>
                                            </li>
                                            <li class="main-nav__item">
                                                <a class="main-nav__link" href="kontakt.html">Kontakt</a>
                                            </li>
                                            ...
                                        </ul>

                                        <!-- po úpravě: -->

                                        <ul class="main-nav__items">
                                            <li class="main-nav__item">
                                                <a class="main-nav__link main-nav__link--active" href="index.html">
                                                    <span class="text">Úvod</span>
                                                </a>
                                            </li>
                                            <li class="main-nav__item">
                                                <a class="main-nav__link" href="kontakt.html">
                                                    <span class="text">Kontakt</span>
                                                </a>
                                            </li>
                                            ...
                                        </ul>
                                    
                                

V takovém případě ale nemůžeme přepsat celý element .main-nav__items, protože odkazy mají různé atributy class (kvůli aktivním stavům podle stránek). V tom případě můžeme použít argumenty --each a --run a přepsat odkazy jeden po druhém a nastavit správné třídy:

                                    
                                        npm run gulp copy -- --each --element ".main-nav__link" --from index.html --run "$after.removeClass('main-nav__link--active').addClass($before.hasClass('main-nav__link--active') ? 'main-nav__link--active' : '')"
                                    
                                

V souboru index.html jsme přidali v navigaci elementy pro ikony a chceme je mít ve všech souborech:

                                    
                                        <!-- před úpravou: -->

                                        <li class="main-nav__item">
                                            <a class="main-nav__link main-nav__link--active" href="index.html">
                                                <span class="text">Úvod</span>
                                            </a>
                                        </li>
                                        <li class="main-nav__item">
                                            <a class="main-nav__link" href="kontakt.html">
                                                <span class="text">Kontakt</span>
                                            </a>
                                        </li>

                                        <!-- po úpravě: -->

                                        <li class="main-nav__item">
                                            <a class="main-nav__link main-nav__link--active" href="index.html">
                                                <span class="text">Úvod</span>
                                                <span class="icon icon--home"><!--icon--></span>
                                            </a>
                                        </li>
                                        <li class="main-nav__item">
                                            <a class="main-nav__link" href="kontakt.html">
                                                <span class="text">Kontakt</span>
                                                <span class="icon icon--contact"><!--icon--></span>
                                            </a>
                                        </li>
                                    
                                

V takovém případě je lepší, než přepisovat celou navigaci, zkopírovat pouze elementy span.icon a vložit je za span.text (kvůli aktivním stavům). Zároveň potřebujeme použít --each, protože ikony mají různé třídy:

                                    
                                        npm run gulp copy -- --each --element ".main-nav__link .icon" --from index.html --after ".main-nav__link .text" --x-nl
                                    
                                

Použili jsme také --x-nl, protože nepotřebujeme volný řádek před elementy span.icon.

Příklad bude fungovat pouze v případě, že ikony jsou u všech položek.

Upravili jsme v index.html elementy .main-header, ale každý stránka má vlastní nadpis h1, který potřebujeme zachovat:

                                    
                                        npm run gulp copy -- --element ".main-header" --from index.html --run "$after.find('h1').replaceWith($before.find('h1'))"
                                    
                                

Místo komponentu BEST-LINKS chceme použít komponent LAST-VIEWED-LINKS z index.html:

                                    
                                        npm run gulp copy -- --component last-viewed-links --from index.html --replace best-links
                                    
                                

Do index.html jsme přidali komponent DIALOG, který chceme vložit do všech souborů za komponent PAGE-FOOTER:

                                    
                                        npm run gulp copy -- --component dialog --from index.html --after page-footer
                                    
                                

V index.html jsme vytovřili galerii u komponentu HOME-ABOUT. Element má tedy třídu home-about__gallery. Později se ukázalo, že potřebujeme stejnou galerii i na dalších stránkách, takže jsme z ní na stránce subpage.html vytvořili komponent GALLERY. Teď tedy potřebujeme přepsat galerii v index.html:

                                    
                                        npm run gulp copy -- --component gallery --from subpage.html --to index.html --replace-element ".home-about__gallery" --format "E|C"
                                    
                                

Použili jsme také argument --format "E|C", protože až se komponent vloží, tak před ním bude element a za ním další jiný komponent. Tím dosáhneme správného počtu volných řádků mezi elementy a komponenty. (Ačkoliv v tomto případě by původní element měl uzavírací komentář, takže by na konci stejně vzniknul řádek navíc.)

HTML — metodologie

Jednotlivé komponenty, které mají vlastní CSS soubory, se oddělují dvěma prázdnými řádky a komentáři typu <!--––––––––– ** COMPONENT ** –––––––––--><!--––––––––– // COMPONENT // –––––––––-->. Viz Příklad 1.

Konce významných bloků kódů jsou označené komentářem, který obsahuje /, . nebo # a class nebo id příslušného elementu (případně obojí). Viz Příklad 1.

                                    
                                        <body>


                                            <!--––––––––– ** COMPONENT1 ** –––––––––-->


                                            <div class="component1">
                                                ...
                                            </div>
                                            <!-- /.component1 -->


                                            <!--––––––––– // COMPONENT1 // –––––––––-->


                                            <!--––––––––– ** COMPONENT2 ** –––––––––-->


                                            <div class="component2">
                                                ...
                                            </div>
                                            <!-- /.component2 -->


                                            <!--––––––––– // COMPONENT2 // –––––––––-->


                                        </body>
                                    
                                

Některé komponenty mohou být rozšířením jiných (obecnějších) komponentů. Ty se označují jako v Příkladu 2.

Komponent home-section rozšiřující komponent section:

                                    
                                        <body>


                                            <!--––––––––– ** HOME-SECTION | SECTION ** –––––––––-->


                                            <div class="home-section section">
                                                ...
                                            </div>
                                            <!-- /.home-section section -->


                                            <!--––––––––– // HOME-SECTION | SECTION // –––––––––-->


                                        </body>
                                    
                                

Základní pořadí atributů:

  1. class
  2. id
  3. src/href
  4. další
  5. aria-*
  6. data-*

Začátky sekcí dokumentu jsou označeny komentáři tohoto typu:

                                    
                                        <!--————————— SECTION —————————-->
                                    
                                

Nad každou sekcí by měly být dva a pod komentářem jeden prázdný řádek.

Úpravy, spojování a kompilace JS

Upravujte vždy pouze vývojové soubory. Tedy soubory ve složkách /js a /libs.

Některé části mohou být vygenerovány pomocí šablonovacího systému nebo vloženy z jiných souborů. Takový kód se nachází mezi komentáři /* GENERATE: NAME ... *//* /GENERATE: NAME */ Více informací najdete v sekci .

Ke spojování a kompilaci souborů se používá automatizační nástroj Gulp. Jeho nastavení se nachází v souboru /gulpfile.js. V tomto souboru najdete sekci označenou komentářem JS, kde můžete upravit nastavení použitých modulů. V souboru /dev/PATHS.js v objektu PATHS můžete upravit zdroje načítání souborů i složku pro výstup:

  • PATHS.JS_LOAD — skript pro načítání souborů pro spojení.
  • PATHS.JS_OUTPUT — složka pro vytvoření výstupu.
  • PATHS.JS_FILES — soubory skriptů.
  • PATHS.JS_MODULES — soubory modulů.
  • PATHS.LIBS_FILES — soubory knihoven a pluginů.

Soubory se spojují a kompilují pomocí příkazu npm run gulp js a výsledný soubor se vytvoří do složky /build. Najdete tam jak minifikovanou tak i neminifikovanou variantu.

Další moduly a soubory pro spojení a kompilaci se nastavují v souboru /dev/load-js.js. Na začátku souboru je objekt FILES, kde vlastnost je název výsledného souboru a hodnota pole spojovaných souborů. Názvů souborů můžete použít kolik chcete a vytvořit tak specifická spojení pro konkrétní stránky.

Skripty jsou kompilovány z ES2015+ do ES5 pomocí Babelu. Pokud se soubor nemá kompilovat, je možné před cestu k souboru přidat prefix nobabel:. Pokud je modul vytvořen podle standardu ES Modules, je potřeba před cestu (a případně za nobabel:) přídat prefix jsm:. Modul se pak transformuje podle vzoru UMD.

K dispozici jsou funkce, které přidají k cestám souborů prefixy k přislušným složkám i prefixy pro Babel:

  • file(relativePath, isModule = true, useBabel = true) — přidá k souboru prefix PATHS.JS_FILES.
  • mod(relativePath, isModule = true, useBabel = true) — přidá k souboru prefix PATHS.JS_MODULES.
  • lib(relativePath, isModule = false, useBabel = false) — přidá k souboru prefix PATHS.LIBS_FILES.

Parametry:

  • relativePath (String) — relativní cesta k souboru. Zadávejte bez počátečního lomítka.
  • isModule (Boolean) — zda-li se jedná o modul podle ES Modules.
  • useBabel (Boolean) — zda-li kompilovat pomocí Babelu.

K názvu souboru se před příponu .js přidá u minifikované verze .min.

Pokud používáte soubor /dev/load-js.js i pro vývoj, více informací najdete v sekci .

Potřebujeme vytvořit modul Alert:

  1. Vytvoříme soubor Alert.js ve složce /js/modules. K tomu můžeme použít gulp-task mod (viz ).
  2. Přidáme cestu k tomuto souboru do skriptu /dev/load-js.js do objektu FILES pomocí funkce mod.
                                    
                                        //...
                                        var FILES = {
                                                "all.build.js": [
                                                    lib("JQSlider/jqslider.js"), //nějaký plugin pro vytvoření slajdru => "nobabel:libs/JQSlider/jqslider.js"

                                                    mod("Slider.js"), //vlastní modul vytvářející slajdry => "jsm:js/modules/Slider.js"
                                                    mod("Alert.js"), //přidaný soubor s novým modulem Alert => "jsm:js/modules/Alert.js"

                                                    file("init.js") //inicializační skript => "jsm:js/init.js"
                                                ]
                                            };
                                        //...
                                    
                                

Nakonec spojíme soubory příkazem:

                                    
                                        npm run gulp js
                                    
                                

Chceme vytvořit samostatné soubory pro stránku index.html a kontakt.html, protože na stránce s kontaktními informacemi nepotřebujeme modul Slider:

  1. V souboru /dev/load-js.js přidáme do objektu FILES vlastnost contact.build.js.
  2. Jako hodnotu vytvoříme pole potřebných souborů.
                                    
                                        //...
                                        var FILES = {
                                                "all.build.js": [
                                                    lib("JQSlider/jqslider.js"), //nějaký plugin pro vytvoření slajdru

                                                    mod("Slider.js"), //vlastní modul vytvářející slajdry
                                                    mod("Alert.js"), //vlastní modul zobrazující zprávy

                                                    file("init.js") //inicializační skript
                                                ],

                                                "contact.build.js": [ //nový soubor
                                                    mod("Alert.js"), //vlastní modul zobrazující zprávy

                                                    file("init.js") //inicializační skript
                                                ]
                                            };
                                        //...
                                    
                                

Nakonec spojíme soubory příkazem:

                                    
                                        npm run gulp js
                                    
                                

Ve složce /build najdeme soubory all.build.js, all.build.min.js, contact.build.js a contact.build.min.js.

JS — metodologie

Kód je převážně rozdělen do modulů podle vzoru ES Modules.

Každý modul se většinou nachází v samostatném souboru ve složce /js/modules, jehož název je název modulu.

Tyto moduly jsou v inicializačním skriptu (/js/init.js) přiřazené ke globálnímu jménnému prostoru (dále GJP) WNS. GJP je objekt, který vrací modul /js/GNS.js, přiřazený k window. Tento objekt při přetypování na string vrací název jmenného prostoru (WNS).

GJP (GNS.js) také obsahuje vlastnosti (properties), které jsou sdílené všemi moduly. Zejména $/jQuery, $win, $doc, $t ("obalí" element do objektu jQuery) a NAME (název).

GJP (GNS.js) je v modulech importován jako objekt GNS.

Modul zpravidla obsahuje metodu init, která modul inicializuje. Na začátku modulu mohou být konstanty s nastavením. Ty jsou psány velkými písmeny. (Jedná se například o objekty CLASS a SELECTOR, kde je možné přepsat třídy a selektory elementů.)

                                    
                                        /*/js/modules/ModuleName.js*/
                                        import GNS from "./GNS.js"; //globální jmenný prostor

                                        const NAME = "ModuleName"; //název modulu
                                        const NS = `.${GNS}.${NAME}`; //lokální jmenný prostor (např. pro události v jQuery)

                                        const $ = G.jQuery;

                                        const SELECTOR = {}; //selektory elementů

                                        function privateFn() {} //soukromá metoda

                                        function init() {} //inicializační a veřejná metoda

                                        export default { init }; //veřejné metody
                                    
                                
Ukázka struktury běžného modulu.

Moduly je pak možné inicializovat v souboru /js/init.js jako v Příkladu 1:

                                    
                                        import GNS from "./GNS.js";

                                        import ModuleName from "./modules/ModuleName.js";

                                        window[GNS] = window[GNS] || GNS;

                                        GNS.ModuleName = ModuleName;
                                        ModuleName.init();
                                    
                                
Příklad inicializace modulu s návzem ModuleName.

Kód je psán podle standardu ES2015+.

Vygenerování JS modulu

Pomocí gulp-tasku mod je možné vygenerovat soubor se základní strukturou modulu.

Argumenty pro nastavení obsahu:

  • --name, --n — název modulu (a souboru).
  • --dir, --d — složka pro uložení souboru (relativní k PATHS.JS_MODULES).
  • --x-gns — bez globálního jmenného prostoru.
  • --x-ns — bez lokálního jmenného prostoru (bez konstanty NS).
  • --x-jq — bez jQuery.
  • --x-name — bez konstanty NAME.
  • --consts, --const, --c, --objects, --object, --o — objekty (konstanty) na začátku modulu. Možnosti: c: CLASS; i: ID; d: DATA; a: ATTR; s: SELECTOR; ev: EVENT; o: OPTION; e: ELEMENT;
  • --rewrite — dovolí přepsat existující soubor.
                                    
                                        npm run gulp mod -- --n Gallery --o c,s
                                    
                                

Vygeneruje soubor /js/modules/Gallery.js:

                                    
                                        /*jshint esnext: true, evil: true, browser: true, devel: true*/

                                        import GNS from "/js/GNS.js";

                                        const NAME = "Gallery";
                                        const NS = `.${GNS}.${NAME}`;

                                        const $ = NS.jQuery;

                                        const CLASS = {

                                        };

                                        const SELECTOR = {
                                            self: ".gallery"
                                        };

                                        function init() {

                                        }

                                        export default { init };
                                    
                                

Úpravy a spojování CSS

Upravujte vždy pouze vývojové soubory. Tedy soubory ve složkách /css a /libs.

Ke spojování souborů se používá automatizační nástroj Gulp. Jeho nastavení se nachází v souboru /gulpfile.js. V tomto souboru najdete sekci označenou komentářem CSS, kde můžete upravit nastavení použitých modulů. V souboru /dev/PATHS.js v objektu PATHS můžete upravit zdroje načítání souborů i složku pro výstup:

  • PATHS.CSS_LOAD — skript pro načítání souborů pro spojení.
  • PATHS.CSS_OUTPUT — složka pro vytvoření výstupu.
  • PATHS.CSS_FILES — soubory stylů.
  • PATHS.CSS_COMPONENTS — soubory komponentů.
  • PATHS.LIBS_FILES — soubory knihoven a pluginů.
  • PATHS.CSS_IMPORT — složka pro vytvoření souboru, který načítá všechny styly pomocí @import. Tento soubor slouží pro testování stránky s vypnutým JS při vývoji.

Soubory se spojují pomocí příkazu npm run gulp css a výsledný soubor se vytvoří do složky /build. Najdete tam jak minifikovanou tak i neminifikovanou variantu. Tento příkaz také vytváří soubor založený na @import do složky PATHS.CSS_IMPORT.

Kromě spojení souborů, se také přepíší Media Query z pixelů na jednotky em, přidají se prefixované hodnoty a CSS Custom Properties se přepíší skutečnými hodnotami. K tomu se využívá PostCSS.

Další komponenty a soubory pro spojení se nastavují v souboru /dev/load-css.js. Na začátku souboru je objekt FILES, kde vlastnost je název výsledného souboru a hodnota pole spojovaných souborů. Názvů souborů můžete použít kolik chcete a vytvořit tak specifická spojení pro konkrétní stránky.

K dispozici jsou i funkce, které přidají k cestám souborů prefixy k přislušným složkám:

  • file(relativePath) — přidá k souboru prefix PATHS.CSS_FILES.
  • comp(relativePath) — přidá k souboru prefix PATHS.CSS_COMPONENTS.
  • lib(relativePath) — přidá k souboru prefix PATHS.LIBS_FILES.

Parametry:

  • relativePath (String) — relativní cesta k souboru. Zadávejte bez počátečního lomítka.

K názvu souboru se před příponu .css přidá u minifikované verze .min.

Pokud používáte soubor /dev/load-css.js i pro vývoj, více informací najdete v sekci Vývoj šablony — HTML soubory.

Potřebujeme vytvořit komponent alert:

  1. Vytvoříme soubor alert.css ve složce /css/components. K tomu můžeme použít gulp-task comp (viz ).
  2. Přidáme cestu k tomuto souboru do skriptu /dev/load-css.js do objektu FILES pomocí funkce comp.
                                    
                                        //...
                                        var FILES = {
                                                "all.build.css": [
                                                    file("reset.css"), //reset stylů

                                                    lib("JQSlider/jqslider.css"), //plugin pro vytvoření slajdru

                                                    comp("slider.css"), //komponent pro slajdry
                                                    comp("alert.css"), //přidaný soubor s novým komponentem alert
                                                ]
                                            };
                                        //...
                                    
                                

Nakonec spojíme soubory příkazem:

                                    
                                        npm run gulp css
                                    
                                

Chceme vytvořit samostatné soubory pro stránku index.html a kontakt.html, protože na stránce s kontaktními informacemi nepotřebujeme komponent slider:

  1. V souboru /dev/load-css.js přidáme do objektu FILES vlastnost contact.build.css.
  2. Jako hodnotu vytvoříme pole potřebných souborů.
                                    
                                        //...
                                        var FILES = {
                                                "all.build.css": [
                                                    file("reset.css"), //reset stylů

                                                    lib("JQSlider/jqslider.css"), //plugin pro vytvoření slajdru

                                                    comp("slider.css"), //komponent pro slajdry
                                                    comp("alert.css"), //přidaný soubor s novým komponentem alert
                                                ],

                                                "contact.build.css": [ //nový soubor
                                                    file("reset.css"), //reset stylů

                                                    comp("alert.css"), //přidaný soubor s novým komponentem alert
                                                ]
                                            };
                                        //...
                                    
                                

Nakonec spojíme soubory příkazem:

                                    
                                        npm run gulp css
                                    
                                

Ve složce /build najdeme soubory all.build.css, all.build.min.css, contact.build.css a contact.build.min.css.

CSS — metodologie

Selektory stylů jsou vytvářeny metodologií BEM — Block-Element-Modifier. Blok reprezentuje samostatný komponent na stránce. Tomu se přiřadí nějaký název (třída), který pak používají všechny vnořené součásti Bloku (Elementy) jako prefix jejich názvu (třídy). Názvy Elementů se tedy vytvářejí pomocí názvu Bloku následovaným dvěma podtržítky (__) a označením názvu Elementu. Pokud je potřeba Blok nebo Element upravit od výchozího stavu, použijí se Modifikátory, což jsou samostatné třídy, které se vytvoří třídou Bloku nebo Elementu, ke které se přidají dvě pomlčky (--) a název modifikátoru. (Viz Příklad 1.)

Nedůležité elementy nemusí tuto konvenci dodržovat.

Máme komponent main-nav pro vytvoření navigace webu. Blok tedy bude mít třídu .main-nav. Seznam položek, položky a odkazy budou Elementy a budou mít třídy .main-nav__items, .main-nav__item a .main-nav__link. Aktivní odkaz bude potřebovat Modifikátor .main-nav__link--active. Kód tedy bude vypadat následovně:

                                    
                                        <!--––––––––– ** COMPONENT1 ** –––––––––-->


                                        <nav class="main-nav">

                                            <ul class="main-nav__items">

                                                <li class="main-nav__item">
                                                    <a class="main-nav__link main-nav__link--active" href="1.html">...</a>
                                                </li>

                                                <li class="main-nav__item">
                                                    <a class="main-nav__link" href="2.html">...</a>
                                                </li>

                                            </ul>
                                            <!-- /.main-nav__items -->

                                        </nav>
                                        <!-- /.component1 -->


                                        <!--––––––––– // COMPONENT1 // –––––––––-->
                                    
                                
                                    
                                        /*/css/components/main-nav.css*/

                                        /*====================================================================*/
                                        /*----------------------------- MAIN-NAV -----------------------------*/
                                        /*====================================================================*/

                                        .main-nav {...}

                                            .main-nav__items {...}

                                                .main-nav__item {...}

                                                    .main-nav__link {...}

                                                    .main-nav__link--active {...}
                                    
                                

Každý komponent (Blok) má samostatný soubor ve složce /css/components, jehož název je název komponentu (Bloku).

Selektory se vytvářejí tak, aby měly co nejnižší možnou specificitu.

Některé styly jsou přiřazené pomocnými třídami — viz . Některé z těchto tříd mají zvýšenou specificitu pomocí id, konkrétně #rewrite. To například umožňuje elementům nastavovat vlastnosti display a zároveň používat pomocné třídy pro skrytí podle velikosti viewportu (x-desktop).

Pokud je nutné přepsat nějakou z těchto pomocných tříd — což se nedoporučuje kvůli zachování logiky kódu — je vhodné tak učinit přesně stejným způsobem. Tedy přidat na začátek selektoru #rewrite a také použít danou pomocnou třídu. Viz následující příklad:

                                    
                                        <section class="section">
                                            <h1 class="section__title color-primary">Vítejte!</h1>
                                        </section>
                                        <!-- /.section -->
                                    
                                

Potřebujeme-li nutně přepsat třídu color-primary, je vhodné to udělat následujícím způsobem:

                                    
                                        #rewrite .section__title.color-primary {
                                            color: red;
                                        }
                                    
                                

Media Query jsou založené na třech základních bodech: Desktop, Tablet, Mobil. (Konkrétně pro tuto šablonu viz .) Styly, které jsou společné, se nachází mimo @media, rozdílné styly jsou (většinou) ohraničené pro určitou velikost viewportu (mají min-width i max-width). (Například, pokud se jedná o sekvenci změny jedné vlastnosti, tak zde ohraničení být nemusí.)

Hodnoty se zadávájí v pixelech a při sestavení/spojení souborů se přepíší na jednotky em.

Jednotlivé seznamy pravidel stylů jsou seřazeny a odsazeny podle struktury HTML kódu. V některých případech může být určitá část kódu přesunuta na jiné místo, je-li to vzájmu lepší čitelnosti a strukturovanosti (například v případě komplikovaných pozadí, které je tvořeno několika elementy).

Pravidla se píší vždy pod sebe a jsou (povětšinou) seřazena podle následujícího pořadí (seznam neobsahuje všechny možné vlastnosti):

                                
                                    .block__element--modifier {
                                        content

                                        position, top, right, bottom, left, z-index

                                        clear, float

                                        order, flex-grow, flex-shrink, flex-basis, grid-column, grid-row, align-self, justify-self,
                                        display, grid-template, flex-direction, flex-wrap,
                                        align-content, align-items, justify-content, justify-items, gap

                                        box-sizing,
                                        width, min-width, max-width, height, min-height, max-height, padding, margin

                                        perspective, transform-origin, transform

                                        font-family, font-size, font-style, font-variant, font-wieght,
                                        text-indent, text-decoration, text-transform, text-align,
                                        columns, vertical-align, line-height, white-space, word-wrap, letter-spacing

                                        color, text-shadow, background, fill, border, stroke, box-shadow,
                                        list-type, opacity, visibility, filter, mix-blend-mode, backdrop-filter, cursor, appearance

                                        clip, clip-path, text-overflow, overflow, overflow-scrolling, overscroll-behavior

                                        pointer-events, touch-action

                                        animation, transition, will-change

                                        contain
                                    }
                                
                            

V souboru se nachází globální nastavení webu pomocí CSS Custom Properties (CP). Používají se pouze tak, aby bylo možné je při sestavení/spojení souborů přepsat skutečnými hodnotami. Není tak možné využít vlastností CP, které závisí na existenci DOMu.

Velikosti prvků se (preferovaně) nastavují pomocí jednotek rem. Na elementu html je nastavená velikost písma na 6.25%, čímž je možné používat jednotky rem jako by šlo o px.

Vygenerování CSS komponentu

Pomocí gulp-tasku comp je možné vygenerovat soubor se základní strukturou komponentu.

Argumenty pro nastavení obsahu:

  • --name, --n — název komponentu (a souboru).
  • --dir, --d — složka pro uložení souboru (relativní k PATHS.CSS_COMPONENTS).
  • --x-mq — nepřídávat do souboru základní @media breakpointy (vychází z tříd pro skrývání obsahu podle viewportu v /).
  • --x-color — nepřídávat do souboru základní barvy (vychází z tříd pro nastavení barev v /).
  • --sections, --section, --s — seznam sekcí oddělených čárkou (,). (Většinou odpovídá nějakému významnému Elementu podle BEM.)
  • --rewrite — dovolí přepsat existující soubor.
                                    
                                        npm run gulp comp -- --n gallery --s items,controller
                                    
                                

Vygeneruje soubor /css/components/gallery.css:

                                    
                                        /*====================================================================*/
                                        /*----------------------------- GALLERY ------------------------------*/
                                        /*====================================================================*/

                                        .gallery {

                                        }

                                        /*--------------------------------------------------------------------*/
                                        /*------------------------------ ITEMS -------------------------------*/
                                        /*--------------------------------------------------------------------*/

                                        .gallery__items {

                                        }

                                        /*--------------------------------------------------------------------*/
                                        /*---------------------------- CONTROLLER ----------------------------*/
                                        /*--------------------------------------------------------------------*/

                                        .gallery__controller {

                                        }

                                        @media (min-width: 1260px) {}
                                        @media (min-width: 768px) and (max-width: 1259px) {}
                                        @media (min-width: 1024px) and (max-width: 1259px) {}
                                        @media (min-width: 768px) and (max-width: 1023px) {}
                                        @media (max-width: 767px) {}
                                        @media (min-width: 640px) and (max-width: 767px) {}
                                        @media (min-width: 480px) and (max-width: 639px) {}
                                        @media (max-width: 479px) {}

                                        /* Colors:
                                         * primary: currentColor
                                         */
                                    
                                

Generování statického kódu

V HTML nebo CSS souborech je možné pomocí komentářů definovat oblast, do které se vygeneruje statický kód podle šablony a dat gulp-taskem generate.

Použití pouze na vlastní nebezpečí! Funkcionalita není důsledně ověřená a výsledek tak může být jakýkoliv. Před přepsáním se proto zkopíruje aktuální stav upravovaných souborů do složky PATHS.HTML_SAVE. Vyhněte se zejména použití generátorů uvnitř jiných generátorů, pokud si nejste jistí, že rozumíte, jak to funguje — můžete ztratit veškerá data specifikovaná ve vnořém generátoru (data je potřeba do vnořených generátorů předávat z rodičovských).

Šablony a data je možné definovat inline uvnitř kódu nebo v externím souboru.

Podporovány jsou tyto šablonovací enginy / formáty:

Moduly pro EJS a Handlebars nejsou ve výchozím stavu nainstalovány.

Podporovány jsou tyto formáty dat:

Základní definice generátoru

Definice generátoru v HTML:

                                    
                                        <!-- GENERATE: NÁZEV | ŠABLONA | DATA? | ...DALŠÍ NASTAVENÍ? -->

                                        ...vygenerovaný obsah...

                                        <!-- /GENERATE: NÁZEV -->
                                    
                                

Definice generátoru v CSS:

                                    
                                        /* GENERATE: NÁZEV | ŠABLONA | DATA? | ...DALŠÍ NASTAVENÍ? */

                                        ...vygenerovaný obsah...

                                        /* /GENERATE: NÁZEV */
                                    
                                

Jednotlivá nastavení se oddělují znakem |. Před ním i za ním musí být mezera.

Jako NÁZEV lze použít řetězec odpovídající následujícímu regulárnímu výrazu: [A-Za-z0-9-_]+.

ŠABLONUDATA lze definovat jako inline blok nebo jako cestu k souboru relativní podle nastavení v /dev/PATHS.js. V případě, že definujeme inline blok, pak se jako hodnota použije jazyk šablony / formát dat. V případě souboru se formát získá z přípony.

Nastavení cest k souborům v /dev/PATHS.js:

  • GENERATOR_TEMPLATES — složka s šablonami.
  • GENERATOR_TEMPLATES_DATA — složka s daty.

Začíná-li cesta k souboru znakem /, pak je cesta relativní ke kořenové složce.

Cesty k souborům nesmí obsahovat mezeru.

DALŠÍ NASTAVENÍ lze použít pro úpravu zpracování dat u formátů XMLCSV.

XML:

  1. Hodnota ROOT nastaví vlastnost explicitRoot modulu xml2js na true — v datech pro šablonu se objeví i kořenový element.
  2. Hodnota ARRAY nastaví vlastnost explicitArray modulu xml2js na true — data vždy vytvoří pole (i v případě jediného elementu).
                                    
                                        <!-- GENERATE: LIST | tpl.twig | data.xml | NOROOT | ARRAY -->

                                        ...vygenerovaný obsah...

                                        <!-- /GENERATE: LIST -->
                                    
                                
Ukázka možné definice generátoru s XML daty. Pokud nechceme použít kořenový element, můžeme jako hodnotu použít v zásadě cokoliv.

CSV:

  1. Oddělovač dat. Výchozí: ,.
  2. Metoda zpracování dat. Možnosti: OBJECT (použije metodu toObject modulu csvjson), COLUMN (použije metodu toColumnArray modulu csvjson) nebo SCHEMA (použije metodu toSchemaObject modulu csvjson). Výchozí: OBJECT.
  3. Uvozovky. Výchozí: ".

V případě metod OBJECTSCHEMA se data (získané pole) v šabloně přiřadí k vlastnosti data.

                                        
                                            <!-- GENERATE: LIST | tpl.twig | data.csv | ; | COLUMN | ' -->

                                            ...vygenerovaný obsah...

                                            <!-- /GENERATE: LIST -->
                                        
                                    
Ukázka možné definice generátoru s CSV daty.

Definování inline bloků

Inline bloky se oddělují minimálně čtyřmi znaky = (====) na samostatném řádku a musí být odsazené čtyřmi mezerami (stejně jako jejich obsah).

První blok obsahuje kód šablony, druhý data. Je-li pro šablonu použit externí soubor, pak se jako první definují data.

                                        
                                            <!-- GENERATE: LIST | TWIG | JSON
                                                ====
                                                <ul>{% for key, value in items %}
                                                    <li class="item{% if key == active %} active{% endif %}">{{value}}</li>{% endfor %}
                                                </ul>
                                                ====
                                                { "items": [1, 2, 3], "active": 1 }
                                            -->

                                            <ul>
                                                <li class="item">1</li>
                                                <li class="item active">2</li>
                                                <li class="item">3</li>
                                            </ul>

                                            <!-- /GENERATE: LIST -->
                                        
                                    
Zde definujeme generátor se šablonou v systému Twig a s daty ve formátu JSON.

Inline data je možné použít i v případě použití externího souboru. Tato data se potom použijí jako rozšíření dat ze souboru (pomocí metody Object.prototype.assign).

Máme-li v souboru tpl.twig stejnou šablonu a v souboru data.json stejná data jako v příkladu výše. Můžeme přepsat data následujícím způsobem:

                                    
                                        <!-- GENERATE: LIST | tpl.twig | data.json
                                            ====
                                            { "active": 0 }
                                        -->

                                        <ul>
                                            <li class="item active">1</li>
                                            <li class="item">2</li>
                                            <li class="item">3</li>
                                        </ul>

                                        <!-- /GENERATE: LIST -->
                                    
                                

Specifický obsah v generátoru

Někdy je potřeba do šablony vložit specifiký obsah pro danou stránku. To můžeme udělat úpravou dat nebo můžeme označit část kódu následujícím způsobem (tento kód se přidá po vygenerování univerzálního kódu z šablony):

                                    
                                        <!-- CONTENT: NÁZEV -->

                                        <h1>Nadpis</h1>

                                        <!-- /CONTENT: NÁZEV -->
                                    
                                

Jako NÁZEV lze použít řetězec odpovídající následujícímu regulárnímu výrazu: [A-Za-z0-9-_]+.

Takovýto kód se objeví v datech pro šablonu v objektu CONTENT. Znaky - budou nahrazeny znaky _.

Takto mohou vypadat definice generátorů v souborech page1.htmlpage2.html:

                                    
                                        <!-- page1.html -->

                                        <!-- GENERATE: SECTION | tpl.twig -->

                                        <section>

                                            <!-- CONTENT: TITLE -->

                                            <h1>Toto je nadpis souboru 1</h1>

                                            <!-- /CONTENT: TITLE -->

                                        </section>

                                        <!-- /GENERATE: SECTION -->


                                        <!-- page2.html -->

                                        <!-- GENERATE: SECTION | tpl.twig -->

                                        <section>

                                            <!-- CONTENT: TITLE -->

                                            <h1>Soubor 2 má jiný nadpis</h1>

                                            <!-- /CONTENT: TITLE -->

                                        </section>

                                        <!-- /GENERATE: SECTION -->
                                    
                                

V souboru tpl.twig pak může vypadat šablona následovně:

                                    
                                        <section>

                                            {{CONTENT.TITLE}}

                                        </section>
                                    
                                

Odsazení se nijak neupravuje. Změní-li se odsazení v šabloně, nově vygenerovaný kód bude odsazený špatně. Z tohoto důvodu je možné při spuštění generátoru ručně nastavit tuto změnu pomocí argumentu --indent. Jako hodnota se použije řetězec ve formátu "NÁZEV:ZMĚNA ODSAZENÍ,NÁZEV:ZMĚNA ODSAZENÍ", tedy napřiklad "TITLE:4,LIST:-8".

Data v šabloně

V šabloně jsou k dispozici následující data:

  • CURRENT_FILE — název aktuálního souboru.
  • CONTENT — definovaný obsah.
  • Data získaná ze souboru nebo z inline bloku.
  • Jsou-li získaná data pole, pak jsou přiřazena k vlastnosti data.

Speciální tagy

Tagem =GX= je možné označit řádek, který se má po vygenerování kódu odstranit.

inline blocích je možné vložit komentáře tagy =GC==/GC=.

                                    
                                        <!-- GENERATE: LIST | TWIG | JSON
                                            ====
                                            <ul>
                                                =GX={% for value in items %}
                                                <li>{{value}}</li>
                                                =GC= /li =/GC=
                                                =GX={% endfor %}
                                            </ul>
                                            ====
                                            { "items": [1, 2, 3] }
                                        -->

                                        <ul>
                                            <li>1</li>
                                            <!-- /li -->
                                            <li>2</li>
                                            <!-- /li -->
                                            <li>3</li>
                                            <!-- /li -->
                                        </ul>

                                        <!-- /GENERATE: LIST -->
                                    
                                

Bez tagů pro odstranění řádků bude výsledek následující:

                                    
                                        <ul>

                                            <li>1</li>
                                            <!-- /li -->

                                            <li>2</li>
                                            <!-- /li -->

                                            <li>3</li>
                                            <!-- /li -->

                                        </ul>
                                    
                                

Použití

Argumenty:

  • --files, --f — seznam souborů oddělených čárkou (,), u kterých se mají spustit generátory. Cesta je relativní k PATHS.HTML_INPUT, respektive k PATHS.CSS_FILES v případě CSS. Začíná-li cesta znakem /, pak je relativní ke kořenové složce.
  • --generators, --g — seznam generátořů oddělených čárkou (,), které se mají spustit.
  • --indent, --i — nastavení změny odsazení pro specifický obsah. Formát: "NÁZEV:ZMĚNA ODSAZENÍ,NÁZEV:ZMĚNA ODSAZENÍ".
  • --css — vynucení CSS módu.
  • --html — vynucení HTML módu.
  • --x-nested — nespouštět vnořené generátory.
  • --log-data — zobrazit nalezená data v konzoli.

Nepoužívá-li se vynucení módu, pak je detekován podle přípony prvního zadaného souboru.

Výchozí hodnoty pro --files jsou *.html v případě HTML módu*.css v případě CSS módu. Není-li mód zadán, použije se HTML.

Spuštění generátorů LISTSECTION v souboru index.html:

                                    
                                        npm run gulp generate -- --g LIST,SECTION --f index.html
                                    
                                

V šabloně generátoru SECTION jsme specifický obsah TITLE zanořili do dalšího elementu a LIST jsme naopak ze dvou vyjmuli, tím pádem nebude odsazení odpovídající:

                                    
                                        {# před změnou #}

                                        <section>

                                            {{CONTENT.TITLE}}

                                            <section>
                                                <div>

                                                    {{CONTENT.LIST}}

                                                </div>
                                            </section>

                                        </section>

                                        {# po změně #}

                                        <section>

                                            <div>

                                                {{CONTENT.TITLE}}

                                            </div>

                                            {{CONTENT.LIST}}

                                        </section>
                                    
                                

Použijeme proto argument --i (--indent), abychom tuto změnu generátoru oznámili:

                                    
                                        npm run gulp generate -- --g SECTION --i "TITLE:4,LIST:-8"
                                    
                                

Do této složky se ukládají i soubory pro CSS.

Přidání/Odebrání knihovny/pluginu

Pluginy, knihovny a další kód třetích stran se vkládá do složky /libs. Chcete-li, aby soubory byly součástí spojených souborů, je potřeba je přidat do skriptů /dev/load-css.js a /dev/load-js.js.

Ke spojování souborů se používá automatizační nástroj Gulp. Jeho nastavení se nachází v souboru /gulpfile.js. V souboru /dev/PATHS.js v objektu PATHS můžete upravit cestu ke složce vlastností LIBS_FILES.

Chceme přidat plugin pro vytváření tooltipů, který se jmenuje Tip. Potřebujeme, ale také upravit jeho vzhled:

  1. Styly i skripty Tipu vložíme do složky /libs/Tip.
  2. Soubory stylů přidáme do pole FILES v souboru /dev/load-css.js a soubory skriptů do pole FILES v souboru /dev/load-js.js. V obou případech pomocí funkce lib.
  3. Vytvoříme soubor tip.css ve složce /css/components a přidáme vlastní styly. (Je také možné vytvořit podobný soubor i přímo ve složce pluginu.)
  4. Soubor přidáme do pole FILES v souboru /dev/load-css.js pomocí funkce comp.
  5. Plugin spustíme například v inicializačním skriptu /js/init.js.
                                    
                                        /*/dev/load-css.js*/
                                        var FILES = {
                                            "all.build.css": [
                                                //...další knihovny
                                                lib("Tip/tip.css"), //styly pluginu

                                                //...další komponenty
                                                comp("tip.css") //vlastní styly
                                            ]
                                        };

                                        /*/dev/load-js.js*/
                                        var FILES = {
                                            "all.build.js": [
                                                //...další knihovny
                                                lib("Tip/tip.js"), //skript pluginu

                                                //...moduly

                                                file("init.js") //inicializační skript
                                            ]
                                        };
                                    
                                
                                    
                                        /*/css/components/tip.css*/
                                        .tip {
                                            background-color: white;
                                        }

                                            .tip__content {
                                                color: black;
                                            }
                                    
                                
                                    
                                        /*/js/init.js*/
                                        var tip = new Tip({
                                            hide: 5000
                                        });
                                    
                                

Nakonec spojíme soubory příkazem:

                                    
                                        npm run gulp css js
                                    
                                

Pro kód knihoven a pluginů a vlastní kód šablony je možné vytvořit samostatné soubory přidáním dalších souborů (vlastností objektu FILES) do souborů /dev/load-css.js a /dev/load-js.js.

Ikony — PNG a SVG sprity

Ikony v SVG jsou (většinou) vložené pomocí spritu, tedy souboru, který sjednocuje více souborů do jednoho. Buď pomocí elementů symbol nebo view.

Ne všechny prohlížeče (IE) podporují načítání symbolů z externího zdroje. Proto se k tomu používá knihovna .

Jednotlivé SVG soubory lze spojit automatizačním nástrojem Gulp příkazem npm run gulp svg. Nastavení se nachází v souboru /gulpfile.js v sekci SVG-SPRITE. Soubory musí být vložené ve složce /img/svg-sprite/src. Výsledné soubory se vytvoří do složek /img/svg-sprite/symbol/svg a /img/svg-sprite/view/svg podle typu.

Cestu pro vstupní soubory a pro výstup můžete nastavit v souboru /dev/PATHS.js:

  • PATHS.SVG_INPUT — vstupní soubory.
  • PATHS.SVG_OUTPUT — složka pro vytvoření výstupu.

Ikonám se přídá id, pomocí kterého lze ikony ze spritu získat. Id tvoří prefix icon- a název souboru.

Chceme na webu použít ikonu search.svg:

  1. Soubor search.svg se vloží do složky /img/svg-sprite/src.
  2. Spustí se příkaz npm run gulp svg.
  3. V HTML se pak ikona vloží následovně (třída icon není povinná):
                                    
                                        <svg class="icon">
                                            <use xlink:href="img/svg-sprite/symbol/svg/sprite.symbol.svg#icon-search"></use>
                                        </svg>
                                    
                                

Jsou-li použité ikony v PNG, pak jsou většinou vložené pomocí spritu /img/sprite.png. Sprite je možné přiřadit k elementu třídou icon.

Ve složce /img také bude soubor pro vytvoření spritu. Buď ve formátu .psd nebo .afdesign.

Použití kódu

HTML soubory — obecně

HTML soubory jsou rozdělené do několika sekcí, které jsou označené komentáři typu <!--———————————— SECTION ————————————-->.

Komentáře typu <!--––––––––– ** COMPONENT ** –––––––––--><!--––––––––– // COMPONENT // –––––––––--> označují začátky a konce jednotlivých komponentů.

Některé části mohou být vygenerovány pomocí šablonovacího systému nebo vloženy z jiných souborů. Takový kód se nachází mezi komentáři <!-- GENERATE: NAME ... --><!-- /GENERATE: NAME --> Více informací najdete v sekci .

Styly jsou vložené v elementu head v sekci <!--— STYLES —--> a skripty na konci elementu body v sekci <!--— JAVASCRIPT —-->. Soubory pro produkční verzi jsou označené komentáři <!--prod--> a <!--/prod--> a pro vývoj <!--dev--> a <!--/dev-->. Pro další informace o sekcích a vývojových soborech viz .

Kód CSS a JS upravujte vždy v nespojených (tedy ve vývojových) souborech, tzn. ve složkách /css a /js. Upravený kód je pak potřeba spojit pomocí příslušného gulp-tasku. Více viz a .

Na začátku elementu body se nachází navigace pro zajištění přístupnosti webu. (Pokud po zobrazení stránky stisknete tab, zobrazí se postupně odkazy na hlavní menu a obsah.)

Obsah generovaný JavaScriptem

V případě, že jde o vypsání nějaké hodnoty do dokumentu (například výsledek výpočtu), pak má většinou cílový element nějakou třídu začínající js-:

                                    
                                        <p class="calc__result">Výsledek je: <span class="js-calc__result">1 000</span> Kč</p>
                                    
                                
Ukázka, jakým způsobem může být realizováno zobrazení výsledku cenové kalkulačky.

Pokud se jedná o komplexnější obsah, pak v HTML bude element script obsahující potřebnou šablonu. Místo, kde se má vložit obsah, pak bude označeno speciálními tagy: {{tag}}. Viz Příklad 2:

                                    
                                        <script id="list__item-template" type="text/html">
                                            <li class="list__item {{isActive}}">
                                                {{content}}
                                            </li>
                                        </script>
                                    
                                
Ukázka, jakým způsobem může být realizováno vytvoření nějakého seznamu pomoci JavaScriptu.

Přístup k JS modulům

Moduly jsou přiřazeny ke jmennému prostoru window.WNS, což je objekt, který lze v dalších modulech získat také importováním /js/GNS.js. K veřejným metodám (API) jednotlivých modulů můžete tedy přistupovat pomocí:

                                    
                                        //v modulu
                                        import GNS from "/js/GNS.js";

                                        GNS.ModuleName.publicMethod();

                                        //mimo modul
                                        window.WNS.ModuleName.publicMethod();
                                    
                                
Ukázka, jak zavolat metodu publicMethod u modulu ModuleName.

Základní @media breakpointy

Zařízení Velikost viewportu Název v kódu
Desktop 78px–75px desktop
Tablet 48px+ tablet
Tablet velký 64px+ tablet-l
Tablet malý 48px+ tablet-s
Mobil 47px–9375px mobile
Mobil velký 40px+ mobile-l
Mobil střední 30px+ mobile-m
Mobil malý 29px–9375px mobile-s

Jsou-li k dispozici modifikační nebo pomocné třídy, mají zpravidla postfixy uvedené ve třetím sloupci. Například třídy pro skrývání elementů na tabletech vypadají následovně: x-tablet, x-tablet-l a x-tablet-s.

css/main.css

V souboru se nastavují základní globální styly obsahu webu. Chcete-li upravit konkrétní element, je vhodné pro něj vytvořit samostatnou třídu nebo před selektor tagu přidat selektor komponentu, jehož je element součástí..

Přepisování stylů pomocí názvů tagů může způsobit nepředvídatelné výsledky ve zbytku stránky.

css/utility.css

Soubor obsahuje pomocné třídy (a styly) pro stylování webu. Jejich funkce je popsaná uvnitř souboru. Zde je jen výběr nejdůležitějších:

Třída Popis Poznámka
center Centruje obsah stránky podle maximální šířky.
push-footer Zajišťuje, aby patička byla vždy ve spodu okna prohlížeče. Patička stránky musí být následující element a mít flex-shrink: 0.
visually-hidden Skryje obsah, ale zůstane přístupný pro čtečky obrazovek apod.
x-no-js Skryje obsah při vypnutém JavaScriptu.
x-js Skryje obsah při zapnutém JavaScriptu.
x-desktop, x-tablet, x-mobile, … Skryje obsah podle velikosti viewportu. Více viz .
color-primary, bg-primary, bd-primary, hf-color-primary, active-color-primary, … red Nastavuje barvu textu/pozadí/rámečku/výplně/čáry. Předpona hf- nastavuje barvu při :hover a :focus. Předpona active- nastavuje barvu u elementů s modifikátorem --active nebo u jejich potomků.
font-primary Nastavuje font na inherit.
hf-opacity Snižuje opacity pri :hover a :focus.

Některé třídy mají zvýšenou specificitu pomocí id. Pokud je nutné přepsat některou z pomocných tříd, pak je vhodné pro to použít stejný způsob včetně dané třídy, tedy například #rewrite .block__element.color-primary {}. Viz také

css/custom-properties.css

Soubor obsahuje základní nastavení globálních promněnných webu pomocí CSS Custom Properties (CP). Jedná se zejména o:

  • obecná nastavení webu (maximální šířka, odsazení, …) — prefix --page
  • barvy — prefix --color
  • písma — prefix --font
  • přechody — prefix --transition

CP se při sestavení/spojení souborů přepíší pomocí PostCSS a pluginu postcss-css-variables skutečnými hodnotami. Není tak možné využít vlastností CP, které závisí na existenci DOMu.

Obrázky/fotky vytvořené pomocí SVG

Některé obrázky jsou vytvořené pomocí SVG, čímž lze získat funkcionalitu object-fit: cover i v prohlížečích, které ji nepodporují. Pro správnou funkčnosti musí mít atribut viewBox rozměry obrázku, tedy 0 0 [šířka] [výška] (nebo alespoň musí výška a šířka odpovídat poměru stran).

Pro simulaci atributu alt, je možné elementu přidat atribut aria-labelledby, kde se jako hodnota použije id elementu title uvnitř svg.

                                    
                                        <svg viewBox="0 0 1920 1080" preserveAspectRatio="xMidYMid slice" overflow="hidden" aria-labelledby="title">
                                            <title id="title">Popis obrázku</title>
                                            <image xlink:href="img/img.jpg" width="100%" height="100%" x="0" y="0"/>
                                        </svg>
                                    
                                

AriaButton: zobrazování/skrývání elementů

Modul AriaButton slouží k vytvoření přístupného (accessible) přepínání prvků na stránce.

Použití: elementu button se přidá třída js-aria-button a minimálně atribut aria-pressed. Pokud tlačítko zobrazuje nějaký skrytý element, je potřeba přidat atribut aria-expanded a atribut aria-controls, do kterého se zadá id zobrazovaného elementu.

Pokud má element atribut aria-controls, pak se elementu s příslušným id přidá třída js-aria-button__target a při přepnutí do aktivního stavu (aria-expanded="true") se přidá třída js-aria-button__target--expanded.

Při přepnutí se na elementu (.js-aria-button) spustí událost ariabutton__change. V objektu události pak jsou k dispozici vlastnosti detail.state, detail.targetdetail.click (označuje, jestli došlo ke změně pomocí kliknutí nebo metody click).

Aria atributy nikdy neměňte jinak než pomocí metody click na příslušném elementu nebo pomocí metod setStatetoggleState v modulu.

Takto můžeme vytvořit jednoduché přepínání menu:

                                    
                                        <button class="menu__opener js-aria-button" aria-pressed="false" aria-expanded="false" aria-controls="menu__list">
                                            Menu
                                        </button>
                                        <ul class="menu__list" id="menu__list">...</ul>
                                    
                                
                                    
                                        .menu__list {
                                            display: none;
                                        }

                                        .menu__opener[aria-expanded="true"] ~ .menu__list {
                                            display: block;
                                        }
                                    
                                

V kódu se často nachází i kód pro zajištění funkčnosti při vypnutém JavaScriptu. Většinou se k tomu používá input typu checkbox:

                                    
                                        <input class="menu__toggle x-js" id="menu__toggle" type="checkbox">

                                        <label class="menu__opener x-js" for="menu__toggle">
                                            Menu
                                        </label>

                                        <button class="menu__opener js-aria-button x-no-js" aria-pressed="false" aria-expanded="false" aria-controls="menu__list">
                                            Menu
                                        </button>

                                        <ul class="menu__list" id="menu__list">...</ul>
                                    
                                
                                    
                                        .menu__list {
                                            display: none;
                                        }

                                        .no-js .menu__toggle:checked ~ .menu__list,
                                        .js .menu__opener[aria-expanded="true"] ~ .menu__list {
                                            display: block;
                                        }
                                    
                                

Použité knihovny a pluginy

jQuery

Knihovna pro usnadnění práce například s DOMem, AJAXem, událostmi nebo animacemi.

SVG for Everybody

Podpora pro externí SVG sprity.

focus-within polyfill

Vlastní polyfill pro CSS selektor :focus-within.

Polyfill přidává elementům odpovídajícím selektoru :focus-within atribut focus-within="true".

CSS pak atribut můžeme použít takto:

                                    
                                        .block[focus-within] .block__element {
                                            display: block;
                                        }

                                        .block:focus-within .block__element {
                                            display: block;
                                        }
                                    
                                

Selektory je nutné rozdělit, protože nepodporující prohlížeče ignorují celou sadu pravidel, pokud jeden ze selektorů v seznamu nepodporují.

Obrázky a fotky

Obrázky a fotky se nacházejí ve složce /img.

JPG, GIF, SVG a PNG lze optimalizovat pomoci automatizačního nástroje Gulp. Příkaz npm run gulp images optimalizuje soubory, které se nacházejí ve složce /img/src a vytvoří je do složky /img.

Cestu pro vstupní soubory a pro výstup můžete nastavit v souboru /dev/PATHS.js:

  • PATHS.IMG_INPUT — vstupní soubory.
  • PATHS.IMG_OUTPUT — složka pro vytvoření výstupu.

Nastavení optimalizace se nachází v souboru /gulpfile.js v sekci označené IMAGES-OPTIMIZATION.

Nastavení kvality JPG lze upravit pomocí --jpg-quality (výchozí: 65):

                                
                                    npm run gulp images -- --jpg-quality 85
                                
                            

Funkcionalita není důsledně ověřená a nemusí být úplně optimální. Více informací najdete na stránce modulu gulp-imagemin.

Další informace

Critical CSS

Pomocí automatizačního nástroje Gulp je možné vytvořit tzv. Cricical CSS. Jeho podstatou je vložit do stránky pouze ty styly, které jsou nutné pro načtení webu, a zbytek se stáhne asynchronně.

Příkazem npm run gulp critical se do složky /critical vytvoří buď samostatný CSS soubor nebo HTML soubor s inline styly. Druhou možnost lze nastavit argumentem --inline. Nastavení je v souboru /gulpfile.js v sekci CRITICAL-CSS.

Také můžete změnit velikost viewportu, pro který se mají zachovat styly, pomocí argumentů --width a --height. Výchozí hodnoty jsout 1024.

                                    
                                        npm run gulp critical -- --width 1920 --height 1080 --inline
                                    
                                
Příklad kódu pro vytvoření cricical CSS pro velikost viewportu 1920x1080, který se vloží přímo do HTML.

Cestu pro HTML soubory a pro výstup můžete nastavit v souboru /dev/PATHS.js:

  • PATHS.HTML — vstupní HTML soubory.
  • PATHS.CRITICAL_OUTPUT — složka pro vytvoření výstupu.

Funkcionalita není důsledně ověřená a nemusí být úplně optimální. Více informací najdete na stránce modulu critical.

Gulp-tasky

Nastavení gulp-tasků se nachází v souboru /gulpfile.js. U každého je k dispozici dokumentace.

  • watch — sledování změn souborů. Viz .
  • build — spojení a minifikace stylů a skriptů a použití souborů v HTML souborech. Spustí gulp-tasky js, css a prod. Viz .
  • prod, dev — přepínání mezi produkčními a vývojovými soubory v HTML souborech. Viz .
  • copy — kopírování sekci, komponentů a elementů mezi HTML soubory. Viz
  • edit — úprava HTML souborů pomocí gulp-cheerio. Viz .
  • htmlsave, recoversave, clearsave — uložení a obnova HTML zálohy. Viz , , .
  • css — spojení a minifikace stylů. Viz
  • comp — vygenerování souboru pro CSS komponent. Viz .
  • js — spojení a minifikace skriptů. Viz
  • mod — vygenerování souboru pro JS modul. Viz .
  • generate — vygenerování statického kódu. Viz .
  • svg — vytvoření jednoho SVG souboru z několika (SVG spritu). Viz .
  • critical — vygenerování critical CSS. Viz .
  • images — optimalizace (zmenšení) obrázků. Viz .

Nikdy nespouštějte dva gulp-tasky používající stejné soubory najednou!