@moRtenDk #drUpaltWIG - DrupalCon | Be Human, Think … · tHemIng DRUpALCoN BaRCElONA 2015 DRUpAl...

Post on 07-Jun-2018

216 views 0 download

transcript

@moRtenDk #drUpaltWIG

7

@moRtenDk #drUpaltWIG

tHemIngDRUpALCoN BaRCElONA 2015

DRUpAl 8

@moRtenDk #drUpaltWIG

SLIdES aRE oNLInE In 60 MInUTEs

sLidEs

@moRtenDk #drUpaltWIG

@morTenDk

CLAsSy MAInTAInER

GEEk RÖYALe THE ANGrY

THEmER

TaG1 CONsULTiNG

@moRtenDk #drUpaltWIG

@MOrTENdK

@moRtenDk #drUpaltWIG

#DRuPALtWiG

@moRtenDk #drUpaltWIG

sOrryRc 1

@moRtenDk #drUpaltWIG

bOoOOooOoLET THE ANGeR OuT

@moRtenDk #drUpaltWIG

sTocKhoLm sYndRome

@moRtenDk #drUpaltWIG

DRUpAL7 MARkUP

@moRtenDk #drUpaltWIG

“IT’S A FEAtUrE”

dIviTis<DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV><DIV>

</DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV>

@moRtenDk #drUpaltWIG

5000LINeS Of PHpTEMpLATe.PHp

TotAllY oK

@moRtenDk #drUpaltWIG

<div class=“foo bar baz foo-more-more bar-more-yet another one”>

fEatUreTHE CLAsS SoUP IS AnOTHeR

@moRtenDk #drUpaltWIG

nO mOre aAaaRgh!

@moRtenDk #drUpaltWIG

nEw

tHemE eNgiNe

GOOd-BYe PHPtEMPlAtEHELlO TwIG

@moRtenDk #drUpaltWIG

tHemE fUncTioNs

dEad!

@moRtenDk #drUpaltWIG

tWig tEmpLatEs

EVErYTHiNG iS

BLOcK.HtML.tWiG

MARk.HTmL.TwIG

TABlE.HtML.tWiG

PAGe.HTmL.TwIGNODe.HTmL.TwIG

VIEw.HTmL.TwIG

FIElD.HtML.tWiG IMAgE-WiDGEt.HTmL.TwIG

@moRtenDk #drUpaltWIG

tHemE iS iN cOntRolThE

OF mARKuP & CSs

@moRtenDk #drUpaltWIG

uNleArn pHptEmpLa

te<? pHP dIe(‘PHPtEMPlAtE’) ?>

@moRtenDk #drUpaltWIG

REAdY?

@moRtenDk #drUpaltWIG

tWigDRUpAl 8

@moRtenDk #drUpaltWIG

IS a “MODeRN” TEmPLAtE LaNGUaGe -> sYMPhONY

USEd BY OTHeR SySTEmS + It’S EaSY tO LeARN :)

tWig

@moRtenDk #drUpaltWIG

{{ var }} {# comment #}

{% functionality %}

{ # %

@moRtenDk #drUpaltWIG

{{ data.is.here }}

{{ also.this[#hashtags] }}

vAr DriLliNg$yo[‘drupal_where ’]->is[‘und’][0]->my_data7

@moRtenDk #drUpaltWIG

{{ var|makemepretty(‘now’) }}

fUncTionPIPe

TWIg FUnCTIoNVaR

@moRtenDk #drUpaltWIG

{{ username|uppercase }}

MORTENDK

fUncTion(mortendk)

@moRtenDk #drUpaltWIG

{{ ‘Copenhagen’|t }}

{% trans %} by {{ user }} date {{ date }} {% endtrans %}

tRanSlaTe

@moRtenDk #drUpaltWIG

{% if person=“mortendk” %} <h1>Loves Drupal8</h1> {% endif %}

cOntRol

@moRtenDk #drUpaltWIG

{{ sushi|raw}}

aUtoEscApe

SECuRITy IS SOMeTHInG DEVeLOPeRS LIKe

@moRtenDk #drUpaltWIG

{% set foo = “bar” %}

{{ foo }}

bar

cReaTe Var

@moRtenDk #drUpaltWIG

cLasSyTHE DRUpAl 8 BAsE ThEmE

@moRtenDk #drUpaltWIG

7corE

claSsy

<HTmL> .CSs CLAsS=“FoO”

<HTmL> .CSs CLAsS=“FoO”

@moRtenDk #drUpaltWIG

bAseTheMe

corE claSsy

my ThemE

? barTik

sevEn$VArS

@moRtenDk #drUpaltWIG

bAseTheMe

<div> {{ foo }} </div>

corE claSsy“MY tHEMe”

NO bASEtHEMe DEfINEd

@moRtenDk #drUpaltWIG

bAseTheMe

<div class=“node node—article”> {{ foo }} </div>

corE claSsy“MY tHEMe”

BASe THeME: CLAsSY

@moRtenDk #drUpaltWIG

tEmpLatEs

CORe/THeME/cLASsY/*

MODuLES/[MODuLENaME]/*7aniMatiOn eXplaIninG how we MoveD shIt

outTa cOre And Into claSsy

@moRtenDk #drUpaltWIG

dRupAl8 teMplAtes

CORe/THeMES/CLAsSy/

@moRtenDk #drUpaltWIG

dEfiNe BasEthEme

base theme: classy

[THEmENAmE].iNFO.YmL

@moRtenDk #drUpaltWIG

yOu DecIde!

corE claSsy

CLEaN As COrE CLAsSES YOU CAN TRUsT

@moRtenDk #drUpaltWIG

corE

claSsy

7

ZeN

MOThERShIP

wAitAmiNutE!

@moRtenDk #drUpaltWIG

MORtENDk

JOHn ALbIN

corE

claSsy

7

ZeN

MOThERShIP

MAInTAInERS ?

@moRtenDk #drUpaltWIG

@moRtenDk #drUpaltWIG

sEtupSETtING UP a THeME

@moRtenDk #drUpaltWIG

[ROOt]/ThEMEs/[THEmENAmE]

I LiVE wHERe NOw ?

@moRtenDk #drUpaltWIG

tHemE cOnfIg FilEs

*.InFO.yMl *.LiBRArIES.YML *.BrEAKpOINtS.YmL *.ThEmE

@moRtenDk #drUpaltWIG

*.inFo.YmlTHEmE CoNFIgURAtION, CSs & jS

@moRtenDk #drUpaltWIG

BASiC INFo

REGiOnS

LIBrARIeS

REMoVE cSS

@moRtenDk #drUpaltWIG

@moRtenDk #drUpaltWIG

*.liBraRieS.yMlADDiNG jS & CSs TO THE THEmE

@moRtenDk #drUpaltWIG

FOO.INFo.YAmL

FOO.LIBrARIeS.YaML

SLIdER.cSSSLIdER.jS

SLIdER

FOO.CsSBAR.JS

AWEsOmE

@moRtenDk #drUpaltWIG

.INfO.YmL

.LIbRARiES.yML

@moRtenDk #drUpaltWIG

NAMe

DEPeNDEnCIEs

CSS FILeS

*.liBraRieS.yMl

JS fILEs

@moRtenDk #drUpaltWIG

global: version: VERSION css: component: css/user/user.theme.css: {} theme: css/layout.css: {}

cSs OrgAniZingBASe LAYoUt COMpONEnT STAtE THEmE

@moRtenDk #drUpaltWIG

[*].BreAkpOinTs.YmlRESpONSiVE iMAGeS

@moRtenDk #drUpaltWIG

*.BrEAKpOINtS.YmL

@moRtenDk #drUpaltWIG

*.BrEAKpOINtS.YmL

@moRtenDk #drUpaltWIG

[*].TheMe

WAS PHPtEMPlATE.PhP

@moRtenDk #drUpaltWIG

.TheMe

.LIbRARiES.yML

.THeME

@moRtenDk #drUpaltWIG

tOolsHOW TO fIND STUfF & DEbUg

@moRtenDk #drUpaltWIG

sEttIngS.pHp

if (file_exists(__DIR__ . '/settings.local.php')) { include __DIR__ . '/settings.local.php'; }

COPy: SiTES/EXAmPLE.SETtINGs.LOcAL.pHP

TO: SITeS/DeFAUlT/SeTTInGS.lOCAl.PHp

UNCoMMEnT In SEtTINgS.PhP

@moRtenDk #drUpaltWIG

DOWnLOAd DEvEL mODUlE INStALL DEVeL + KINt

INStALL DRUsH DRUsH En KInT

DOCs.DRuSH.oRG/eN/MaSTEr/INsTALl/

dEvel

@moRtenDk #drUpaltWIG

dIsaBle csS cAche

@moRtenDk #drUpaltWIG

THEmE DeBUG FTW!

SERvICEs.YMl

@moRtenDk #drUpaltWIG

FILe NAmE SuGGEsTIOnSFILe NAmE SuGGEsTIOnS

@moRtenDk #drUpaltWIG

PATh TO ACTiVE tEMPlAtE

@moRtenDk #drUpaltWIG

@moRtenDk #drUpaltWIG

kInt{{ kint( foo ) }}

KRUmO FoR DrUPAl 8

{{ content.field_image }}

screenshot af kint fra video

@moRtenDk #drUpaltWIG

SITeS/AlL/DeFAUlT/SeRVIcES.yMl

DRUsH Cr

{{ KInT(FoO) }}

tWig deBug:

@moRtenDk #drUpaltWIG

tEmpLatE sTruCtuRe

EVErYTHiNG iS A TEMpLATe FIlE

@moRtenDk #drUpaltWIG

125 TemPlaTesWE nUKEd THe THeME fUNCtIONs*

TURnED iT AlL INTo A mETRiCFUCkTON

OF tEMPlATEs

@moRtenDk #drUpaltWIG

@moRtenDk #drUpaltWIG

gRouPsdo we really need this here ?

@moRtenDk #drUpaltWIG

tEmpLatE gRouPsLAYoUT

FIElD

DATaSeT

VIEwS

BLOcK CONtENT-EDIt

CONtEnT

MISc

USEr

NAViGATiON

FORm

@moRtenDk #drUpaltWIG

hTml

HTMl.HTmL.TwIG

CSS + Js

HEAdER

@moRtenDk #drUpaltWIG

HTMl.HTmL.TwIG

pAge

PAGe.HTmL.TwIG

@moRtenDk #drUpaltWIG

HTMl.HTmL.TwIGREGiON.hTML.TWIg

REGiON.hTML.TWIg

REGiON.hTML.TWIg

rEgiOn's

PAGe.HTmL.TwIG

@moRtenDk #drUpaltWIG

HTMl.HTmL.TwIG

cOntEnt

BLOcK.HtML.tWiG NODe.HTmL.TwIG VIEw.HTmL.TwIG

REGiON.hTML.TWIg

@moRtenDk #drUpaltWIG

nOde

FIElD.HtML.tWiG

NODe.HTmL.TwIG

FIElD.HtML.tWiGFIElD.HtML.tWiG

FIElD-—IMAgE.HtML.tWiGFIElD.HtML.tWiG

FIElD.HtML.tWiG

@moRtenDk #drUpaltWIG

aLl The fiEldsFIElD.HtML.tWiG FIElD.HtML.tWiG FIElD.HtML.tWiG FIElD.HtML.tWiG

FIElD.HtML.tWiG FIElD.HtML.tWiG FIElD.HtML.tWiG FIElD.HtML.tWiG

FIElD.HtML.tWiG FIElD.HtML.tWiG FIElD.HtML.tWiG FIElD.HtML.tWiG

FIElD.HtML.tWiG FIElD.HtML.tWiG FIElD.HtML.tWiG FIElD.HtML.tWiG

WE’RE gONNa TAlK AbOUT FIElDS lATEr

@moRtenDk #drUpaltWIG

lAyoUtTHE MAGiC Of WItHOUt

@moRtenDk #drUpaltWIG

{{ content|without(‘field’) }}

wIthOut fuNctIonPIPe

NAMeTWIg FUnCTIoN

VaR

@moRtenDk #drUpaltWIG

NODe.HTmL.TwIG

@moRtenDk #drUpaltWIG

conTeNt

imaGe

tagS

wIthOut

@moRtenDk #drUpaltWIG

{{ coNtenT }}

{{ imAge }}

{{ content }}

{{ teXt }} {{ taGs }}

@moRtenDk #drUpaltWIG

{{ coNtenT | WithOut(*) }}

{{ imAge }}

{{ content|without(‘image’) }}

{{ content.image }}

{{ teXt }} {{ taGs }}

@moRtenDk #drUpaltWIG

{{ coNtenT | WithOut(**) }}

{{ imAge }}

{{ content|without(‘image’,‘tags’) }}

{{ content.image }}

{{ teXt }} {{ taGs }}

{{ content.tags }}

@moRtenDk #drUpaltWIG

{{ coNtenT | WithOut(**) }}

{{ imAge }}

{{ content|without(‘image’,‘tags’) }}

{{ content.image }}

{{ teXt }} {{ taGs }}

{{ content.tags }}

{{ neW }}

NEW FIElD

@moRtenDk #drUpaltWIG

CONtEnTnOde.htMl.Twig

@moRtenDk #drUpaltWIG

CONtENT.FIElD_ImAgE

@moRtenDk #drUpaltWIG

CONtENT.FIElD_TaGS

@moRtenDk #drUpaltWIG

fIeldTHE HEArT Of DRuPaL

@moRtenDk #drUpaltWIG

HOW MANy <DiV>S DOEs IT TAKe TO MAKe A “SINgLE fIELd WItH OnE

VaLuE” NO lABEl?

@moRtenDk #drUpaltWIG

@moRtenDk #drUpaltWIG

Yo!

@moRtenDk #drUpaltWIG

Yo!

<div class=“field-items”>

</div>

<div class=“field field-name-field-single field-type-text field-label-hidden”>

</div>

</div>

<div class=“field-item even”> 7

@moRtenDk #drUpaltWIG

Yo!

<div class=“field field--name-field-single field--type-string field--label-hidden field__items”>

</div> CLAsSY

@moRtenDk #drUpaltWIG

Yo!<div> </div>

@moRtenDk #drUpaltWIG

Yo!<div> </div>

ONE DIV ZERo CLaSSEs 100% DrUPAl

@moRtenDk #drUpaltWIG

Yo!<div class=“yolo”> </div>

ONE DIV ZERo CLaSSEs 100% DrUPAl

@moRtenDk #drUpaltWIG

sIngLenAked

WHAt DO I UsE A

<DIv>

dUde grEat

@moRtenDk #drUpaltWIG

WHAtEVErYOU

WANt IT TO

@moRtenDk #drUpaltWIG

fIelD mArkUp

@moRtenDk #drUpaltWIG

fIeldLABeL VALuE

@moRtenDk #drUpaltWIG

SINgLE

MULtIPLe

LABeL

LABeL

}}

@moRtenDk #drUpaltWIG

FIElD.HtML.tWiG

@moRtenDk #drUpaltWIG

SINgLE MULtIPLe

SINgLE + LAbEL MULtIPLe + lABEl

@moRtenDk #drUpaltWIG

LABeL DiSPLaY

mAnaGe DisPlay

@moRtenDk #drUpaltWIG

“INLiNE”

“VISuALLy HIDdEN”

“ABOvE”

@moRtenDk #drUpaltWIG

FIElD.HtML.tWiG

@moRtenDk #drUpaltWIG

NO lABEl

LABeL

@moRtenDk #drUpaltWIG

{% if label_hidden %} {% if multiple %}

{% else %} {% endif %} {% else %} {% if multiple %}

{% else %}

{% endif %} {% endif %}

@moRtenDk #drUpaltWIG

<div> yo </div>

<div> <div> label</div> <div>yo </div> </div>

<div> <div>label</div> <div> <div>yo </div> <div>lo </div> </div> </div>

@moRtenDk #drUpaltWIG

aTtrIbuTesPURe CLaSS

@moRtenDk #drUpaltWIG

<div {{ attributes }}> class=“foo” data-drupal-foo aria-hidden=“true”

aTtrIbuTes

@moRtenDk #drUpaltWIG

CLAsSY

<DIv CLaSs=“FOO FOO-BAR FOO-BAR-BaZ”>

*.TpL.PhP

THEmE FuNCTiOnS

PREpROCeSS

$VArS

DRUpAL7

7

@moRtenDk #drUpaltWIG

@moRtenDk #drUpaltWIG

{% set classes = [ ‘field-' ~ field_name|clean_class ~ ' ] %}

<div {{ attributes.addClass(classes) }}>…</div>

<div class=“tags field-tags”>…

aDdcLass

@moRtenDk #drUpaltWIG

<i {{ attributes.removeClass(red) }}> … </i>

<i class=“blue”>…</i>

<div class=“red blue”> … </div>BAD MODuLE oUTPuT

rEmoVe ClaSs

@moRtenDk #drUpaltWIG

CLAsSYMODuLECORe

<DIv CLaSs=“CORe”>

ESSeNTIaL ClASSeS Ex: “IS-vISIbLE”

@moRtenDk #drUpaltWIG

CLAsSYMODuLECORe

<DIv CLaSs=“CORe MOdUlE”>

$vaR[‘attRibuTes’]->AddCLass(‘modUle’)

@moRtenDk #drUpaltWIG

CLAsSYMODuLECORe

<DIv CLaSs=“CORe MOdULE THEmE”>

{{ ATtRIBuTES.ADDcLASs(‘THEmE’) }}

@moRtenDk #drUpaltWIG

CLAsSYMODuLECORe

<DIv CLaSs=“CORe THeME”>

{{ ATtRIBuTES.REMoVe(‘MODuLE’) }}

@moRtenDk #drUpaltWIG

CLAsSYMODuLECORe

<DIv CLaSs=“THEmE”>

{{ ATtRIBuTES.REMoVe(‘MODuLE’,’CORe’) }}

@moRtenDk #drUpaltWIG

jS- PreFix

<DIv CLaSs=“JS-fOO fOO”>…

$(.jS-FoO) .FOo{…}

@moRtenDk #drUpaltWIG

<div class="blablabla"> {{ attributes .removeClass(‘blablabla’) .addClass(‘hero-main’) .setAttribute('id', 'top') }} <div id="top" class="hero-main">

aTtrIbuTes

@moRtenDk #drUpaltWIG

fIelD & atTriButEs

KISsING IN a TReEEEeEEEeEEEeE

@moRtenDk #drUpaltWIG

<div> yo </div>

<div> <div> label</div> <div>yo </div> </div>

<div> <div>label</div> <div> <div>yo </div> <div>hej </div> </div> </div>

@moRtenDk #drUpaltWIG

<div class=“field field__item”> yo </div>

<div class=“field”> <div class=“field__label”> label</div> <div class=“field__item”>yo </div> </div>

<div class=“field”> <div class=“field__label”>label</div> <div class=“field__items”> <div class=“field__item”>yo </div> <div class=“field__item”>lo </div> </div> </div>

@moRtenDk #drUpaltWIG

LABeL VALuE

.field__item.field__label

.field

@moRtenDk #drUpaltWIG

.field__item.field__label

.field__items

.field

@moRtenDk #drUpaltWIG

FIX THE MARkUP

@moRtenDk #drUpaltWIG

@moRtenDk #drUpaltWIG

ADD & REmOVE CLAsSES

@moRtenDk #drUpaltWIG

@moRtenDk #drUpaltWIG

CHAnGE sTUFf WHeN 8

@moRtenDk #drUpaltWIG

@moRtenDk #drUpaltWIG

{{ attach_library('classy/book-navigation') }}

cSs FilEs In TemPlaTe

@moRtenDk #drUpaltWIG

tWigBloCkMORe COoLNEsS FrOM tWiG

@moRtenDk #drUpaltWIG

datA (pAge.Html.twiG)

PAGe.HTmL.TwIGD8

datA (pAge.Html.twiG)

@moRtenDk #drUpaltWIG

datA (pAge.Html.twiG)

{% block foo %} {% endblock %}

PAGe.HTmL.TwIGD8

datA (pAge.Html.twiG)

@moRtenDk #drUpaltWIG

datA (pAge.Html.twiG)

(paGe-—froNt.hTml.Twig)

{% extends "page.html.twig" %}

PAGe.HTmL.TwIGD8

datA (pAge.Html.twiG)

@moRtenDk #drUpaltWiG

@moRtenDk #drUpaltWIG

PAGe.HTmL.TwIG

PAGe—FROnT.HtML.tWiG

@moRtenDk #drUpaltWIG

PAGe.HTmL.TwIG

PAGe—FROnT.HtML.tWiG

@moRtenDk #drUpaltWIG

hAppY ?ARE YOU NOT ENTeRTAiNED ?

@moRtenDk #drUpaltWiG

SCReENShOt 2.0

@moRtenDk #drUpaltWiG

mEnupAgeRs

ONLy 1 (OnE) tEMPlATE FILe

MENu.HTmL.TwIG

@moRtenDk #drUpaltWiG

pAgerFUN FOR EVErYBOdY ?PAGeR.HtML.tWiG

@moRtenDk #drUpaltWIG

8 thIngS cHanGed

T L ; D L TOO LONg - DIDn'T lISTeN!

@moRtenDk #drUpaltWIG

1. iE sUppOrt?

NO mORE SUPpORT FOR IE6, Ie7 & iE8

@moRtenDk #drUpaltWIG

2. mArkUp CleAnup

HTMl5 CSS IS sMACsS & BEm BAsEd

“MODeRN” PRaCTIcE #iD ReMOVeD SEVeN Is REsPONsIvE

@moRtenDk #drUpaltWIG

jS sEpeRatIonSEPaRATeD

JAVaSCRiPT’S FuNCTiONAlITY CSS STYlING IS sEPArATEd

.JS-FOObAR{ …} .FOoBaR{ COlOR: BLUe}

@moRtenDk #drUpaltWIG

dIviTis

90% OF tHE mARKuP Is GOnE

@moRtenDk #drUpaltWIG

jQueRy DepEndEncy

DONt WAnT 32K Of LOvE ? … THeN DoN’T

@moRtenDk #drUpaltWIG

cLasSy!

CLAsSY SEPaRATeD ThE MaRKUp

FROm COrE

@moRtenDk #drUpaltWIG

sAluTe!FOR THOsE ThAT rOCKeD ThE TwIG

WE sALUtE YoU!

@moRtenDk #drUpaltWIG

i loOovE uUuCOTtSeR

JOEl

LEWiS

EMMa

LAUrII

#FReERUbEN

DAViD HeRNAnDeZ

JOHn ALbINWIM LEErS

JEN LAMpToN

FABiAN

@moRtenDk #drUpaltWiG

DRUpAl 7

@moRtenDk #drUpaltWIG

DRUpAL.oRG/tHEMe-GUiDe/8

DRUpAL.oRG/cODInG-StANDaRDS/CSS

SMAcSS.cOM

TWIg.SEnSIOlABS.ORG/DOCuMENtATIoN

lInks

@moRtenDk #drUpaltWIG

dOwnLoaD d8

BUIlD StUFF NOW!

DRUpAL.oRG/dRUPaL8

@moRtenDk #drUpaltWIG

WEEkLY mEETiNG’S THUrSDAy 17:00 CEt

#DruPalTwig

@moRtenDk #drUpaltWIG

USE TWItTER #DRuPALtWIG

QUEsTIOnS, cOMMeNTS & FEeDBAcK @MOrTENdK

qUesTioNs

@moRtenDk #drUpaltWiG

sEssIonsDRUpALCoN

@moRtenDk #drUpaltWiG

FROnTENd UNiTED BELuGAM

BOF ROOm XXx

FROnTENd UNiTeD

@moRtenDk #drUpaltWiG

ALL WEEk !DRUpAL fRONtEND SPRiNt

CODeR LoUNGe

SPRiNT lEADeRs:(FRoNTEnD UnITEd)

@moRtenDk #drUpaltWIG

FONtS: DAFt BRuSH, BRUsH Up, BiTTEr

ICOnS: SMAlL IcONS 2

cRedIts