COMMER CE & MOBILE SOLUTIONS Magento 2 Community Project Improving state of M2 front-end BARTEK IGIELSKI
 LEAD FRONT-END DEVELOPER
„Front-end devs should make front-end using
 front-end oriented tools” … Yeah, that’s my „wisdom”
LESS to SASS
LESS to SASS Enno Stuurman @SpaarneTweet
• How to simplify code and refactoring? • How to get self-documenting code? • How to start reusing code without letting components influence each other?
Frontend Development Methodology Naming convention + Styles achitecture
BEM Block + Element + Modifier
What is BEM? Component-based approach to web development. The idea behind it is to divide the user interface into independent blocks.
BEM naming convention .block-name .block-name__element-name .block-name--block-modifier .block-name__element-name--element-modifier
Block
Element
Modifier
Independent positioning
<ul> <li> <a> <span></span> </a> </li> </ul> .ul {} .ul > li {} .ul > li > a {} .ul > li > a > span {} <ul class="menu"> <li class="menu__item"> <a class="menu__link"> <span class="menu__text"></span> </a> </li> </ul> .menu {} .menu__item {} .menu__link {} .menu__text {} Typical code BEMed code
Real life example Yey, more code!
https://goo.gl/BFJwHR magento/module-contact/view/frontend/templates/form.phtml Our patient:
<form class="form contact" action="<?php echo $block->escapeUrl($block->getFormAction()); ?>" id="contact-form" method="post" data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>" data-mage-init='{"validation":{}}'> <fieldset class="fieldset"> <legend class="legend"><span><?php echo $block->escapeHtml(__('Write Us')) ?></span></legend><br /> <div class="field note no-label"><?php echo $block->escapeHtml(__('Jot us a note and we’ll get back to you as quickly as possible.')) ?></div> <div class="field name required"> <label class="label" for="name"><span><?php echo $block->escapeHtml(__('Name')) ?></span></label> <div class="control"> <input name="name" id="name" title="<?php echo $block->escapeHtmlAttr(__('Name')) ?>" value="<?php echo $block->escapeHtmlAttr($this->helper('MagentoContactHelperData')->getPostValue('name') ?: $this->hel HelperData')->getUserName()) ?>" class="input-text" type="text" data-validate="{required:true}"/> </div> </div> <div class="field email required"> <label class="label" for="email"><span><?php echo $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> <input name="email" id="email" title="<?php echo $block->escapeHtmlAttr(__('Email')) ?>" value="<?php echo $block->escapeHtmlAttr($this->helper('MagentoContactHelperData')->getPostValue('email') ?: $this- ContactHelperData')->getUserEmail()) ?>" class="input-text" type="email" data-validate="{required:true, 'validate-email':true}"/> </div> </div> <div class="field telephone"> <label class="label" for="telephone"><span><?php echo $block->escapeHtml(__('Phone Number')) ?></span></label> <div class="control"> <input name="telephone" id="telephone" title="<?php echo $block->escapeHtmlAttr(__('Phone Number')) ?>" value="<?php echo $block->escapeHtmlAttr($this->helper('MagentoContactHelperData')->getPostValue('te class="input-text" type="text" /> </div> </div> <div class="field comment required"> <label class="label" for="comment"><span><?php echo $block->escapeHtml(__('What’s on your mind?')) ?></span></label> <div class="control"> <textarea name="comment" id="comment" title="<?php echo $block->escapeHtmlAttr(__('What’s on your mind?')) ?>" class="input-text" cols="5" rows="3" data-validate="{required:true}"><?php echo $block->escapeHt >helper('MagentoContactHelperData')->getPostValue('comment')) ?></textarea> </div> </div> <?php echo $block->getChildHtml('form.additional.info'); ?> </fieldset> <div class="actions-toolbar"> <div class="primary"> <input type="hidden" name="hideit" id="hideit" value="" /> <button type="submit" title="<?php echo $block->escapeHtmlAttr(__('Submit')) ?>" class="action submit primary"> <span><?php echo $block->escapeHtml(__('Submit')) ?></span> </button> </div> </div> </form> Source
<?php $_helper = $this->helper('MagentoContactHelperData'); ?> <form class="form" id="contact-form" action="<?= $block->escapeUrl($block->getFormAction()); ?>" method="post" data-hasrequired="<?= $block->escapeHtmlAttr(__('* Required Fields')) ?>" data-mage-init='{ "validation":{} }' > <h2 class="form__header"> <?= $block->escapeHtml(__('Write Us')) ?> </h2> <p class="form__description"> <?= $block->escapeHtml(__('Jot us a note and we’ll get back to you as quickly as possible.')) ?> </p> <div class="form__field field"> <label class="field__label" for="name"> <?= $block->escapeHtml(__('Name')) ?> </label> <input class="field__input" name="name" id="name" title="<?= $block->escapeHtmlAttr(__('Name')) ?>" value="<?= $block->escapeHtmlAttr($_helper->getPostValue('name') ?: $_helper->getUserName()) ?>" type="text" data-validate="{ required:true }" > </div> <div class="form__field field"> <label class="field__label" for="email"> <?= $block->escapeHtml(__('Email')) ?> </label> <input class="field__input" id="email" type="email" name="email" title="<?= $block->escapeHtmlAttr(__('Email')) ?>" value="<?= $block->escapeHtmlAttr($_helper->getPostValue('email') ?: $_helper->getUserEmail()) ?>" data-validate="{ required:true, 'validate-email':true }" > </div> Refactored + formatted + BEM <div class="form__field field"> <label class="field__label" for="telephone"> <?= $block->escapeHtml(__('Phone Number')) ?> </label> <input class="field__input" name="telephone" id="telephone" title="<?= $block->escapeHtmlAttr(__('Phone Number')) ?>" value="<?= $block->escapeHtmlAttr($_helper->getPostValue('telephone')) ?>" type="text" > </div> <div class="form__field field"> <label class="field__label" for="comment"> <?= $block->escapeHtml(__('What’s on your mind?')) ?> </label> <textarea class="field__input field__input--textarea" id="comment" name="comment" title="<?= $block->escapeHtmlAttr(__('What’s on your mind?')) ?>" cols="5" rows="3" data-validate="{ required:true }" ><?= $block->escapeHtml($_helper->getPostValue('comment')) ?></textarea> </div> <?= $block->getChildHtml('form.additional.info'); ?> <div class="form__actions actions-toolbar"> <div class="actions-toolbar__primary"> <input class="form__hidden" type="hidden" name="hideit" value="" > <button class="actions-toolbar__button button" title="<?= $block->escapeHtmlAttr(__('Submit')) ?>" type="submit" > <?= $block->escapeHtml(__('Submit')) ?> </button> </div> </div> </form>
Source - Refactored HTML elements count 31 - 19 CSS Class count 36 (20 unique) - 27 (15 unique)
<form class="form contact"> <fieldset class="fieldset"> <legend class="legend"> <span></span> </legend> <br /> <div class="field note no-label"></div> <div class="field name required"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text"/> </div> </div> <div class="field email required"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text"/> </div> </div> <div class="field telephone"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text" /> </div> </div> <div class="field comment required"> <label class="label" for="comment"> <span></span> </label> <div class="control"> <textarea class="input-text"></textarea> </div> </div> </fieldset> <div class="actions-toolbar"> <div class="primary"> <input /> <button class="action submit primary"> <span></span> </button> </div> </div> </form> <form class="form"> <h2 class="form__header"></h2> <p class="form__description"></p> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <textarea class="field__input field__input--textarea"></textarea> </div> <div class="form__actions actions-toolbar"> <div class="actions-toolbar__primary"> <input class="form__hidden"> <button class="actions-toolbar__button button"></button> </div> </div> </form>
<form class="form contact"> <fieldset class="fieldset"> <legend class="legend"> <span></span> </legend> <br /> <div class="field note no-label"></div> <div class="field name required"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text"/> </div> </div> <div class="field email required"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text"/> </div> </div>
<div class="field telephone"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text" /> </div> </div> <div class="field comment required"> <label class="label" for="comment"> <span></span> </label> <div class="control"> <textarea class="input-text"></textarea> </div> </div> </fieldset> <div class="actions-toolbar"> <div class="primary"> <input /> <button class="action submit primary"> <span></span> </button> </div> </div> </form>
<form class="form"> <h2 class="form__header"></h2> <p class="form__description"></p> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <textarea class="field__input field__input--textarea"></textarea> </div> <div class="form__actions actions-toolbar"> <div class="actions-toolbar__primary"> <input class="form__hidden"> <button class="actions-toolbar__button button"></button> </div> </div> </form>
Sort of… Roadmap
Magento UI
 It should to provide ready to use components, not only set of (little bit overcomplicated) mixins.
Rebuild „Blank” theme
 Using Magento UI and our development methodology
Improve Frontools 100% replacement of CLI methods related to front-end work
Estimated release time…
We need some help! Specify 3 points of pain in M2 and send them at bartek.igielski@snow.dog Plase be specifyc! I.e. saying just „lack of documentation” sucks. Specify what part of app need (better) docs.
How to stay updated? Twitter @Igloczek <- it’s me :) @SnowdogApps <- Snowdog (you don’t say!) GitHub https://github.com/SnowdogApps/magento2-theme-blank-sass https://github.com/SnowdogApps/magento2-frontools Magento Forums https://community.magento.com/t5/Less-to-Sass-Community-Project/bd-p/less-to-sass
Q & A Time! Let’s stay in touch: Twitter: @igloczek Blog: iglo.tech bartek.igielski@snow.dog

Improving state of M2 front-end - Magento 2 Community Project

  • 1.
    COMMER CE &MOBILE SOLUTIONS Magento 2 Community Project Improving state of M2 front-end BARTEK IGIELSKI
 LEAD FRONT-END DEVELOPER
  • 2.
    „Front-end devs should makefront-end using
 front-end oriented tools” … Yeah, that’s my „wisdom”
  • 3.
  • 4.
    LESS to SASS EnnoStuurman @SpaarneTweet
  • 5.
    • How tosimplify code and refactoring? • How to get self-documenting code? • How to start reusing code without letting components influence each other?
  • 6.
    Frontend Development Methodology Namingconvention + Styles achitecture
  • 7.
  • 8.
    What is BEM? Component-basedapproach to web development. The idea behind it is to divide the user interface into independent blocks.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
    <ul> <li> <a> <span></span> </a> </li> </ul> .ul {} .ul >li {} .ul > li > a {} .ul > li > a > span {} <ul class="menu"> <li class="menu__item"> <a class="menu__link"> <span class="menu__text"></span> </a> </li> </ul> .menu {} .menu__item {} .menu__link {} .menu__text {} Typical code BEMed code
  • 15.
  • 16.
  • 17.
    <form class="form contact" action="<?phpecho $block->escapeUrl($block->getFormAction()); ?>" id="contact-form" method="post" data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>" data-mage-init='{"validation":{}}'> <fieldset class="fieldset"> <legend class="legend"><span><?php echo $block->escapeHtml(__('Write Us')) ?></span></legend><br /> <div class="field note no-label"><?php echo $block->escapeHtml(__('Jot us a note and we’ll get back to you as quickly as possible.')) ?></div> <div class="field name required"> <label class="label" for="name"><span><?php echo $block->escapeHtml(__('Name')) ?></span></label> <div class="control"> <input name="name" id="name" title="<?php echo $block->escapeHtmlAttr(__('Name')) ?>" value="<?php echo $block->escapeHtmlAttr($this->helper('MagentoContactHelperData')->getPostValue('name') ?: $this->hel HelperData')->getUserName()) ?>" class="input-text" type="text" data-validate="{required:true}"/> </div> </div> <div class="field email required"> <label class="label" for="email"><span><?php echo $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> <input name="email" id="email" title="<?php echo $block->escapeHtmlAttr(__('Email')) ?>" value="<?php echo $block->escapeHtmlAttr($this->helper('MagentoContactHelperData')->getPostValue('email') ?: $this- ContactHelperData')->getUserEmail()) ?>" class="input-text" type="email" data-validate="{required:true, 'validate-email':true}"/> </div> </div> <div class="field telephone"> <label class="label" for="telephone"><span><?php echo $block->escapeHtml(__('Phone Number')) ?></span></label> <div class="control"> <input name="telephone" id="telephone" title="<?php echo $block->escapeHtmlAttr(__('Phone Number')) ?>" value="<?php echo $block->escapeHtmlAttr($this->helper('MagentoContactHelperData')->getPostValue('te class="input-text" type="text" /> </div> </div> <div class="field comment required"> <label class="label" for="comment"><span><?php echo $block->escapeHtml(__('What’s on your mind?')) ?></span></label> <div class="control"> <textarea name="comment" id="comment" title="<?php echo $block->escapeHtmlAttr(__('What’s on your mind?')) ?>" class="input-text" cols="5" rows="3" data-validate="{required:true}"><?php echo $block->escapeHt >helper('MagentoContactHelperData')->getPostValue('comment')) ?></textarea> </div> </div> <?php echo $block->getChildHtml('form.additional.info'); ?> </fieldset> <div class="actions-toolbar"> <div class="primary"> <input type="hidden" name="hideit" id="hideit" value="" /> <button type="submit" title="<?php echo $block->escapeHtmlAttr(__('Submit')) ?>" class="action submit primary"> <span><?php echo $block->escapeHtml(__('Submit')) ?></span> </button> </div> </div> </form> Source
  • 18.
    <?php $_helper = $this->helper('MagentoContactHelperData'); ?> <formclass="form" id="contact-form" action="<?= $block->escapeUrl($block->getFormAction()); ?>" method="post" data-hasrequired="<?= $block->escapeHtmlAttr(__('* Required Fields')) ?>" data-mage-init='{ "validation":{} }' > <h2 class="form__header"> <?= $block->escapeHtml(__('Write Us')) ?> </h2> <p class="form__description"> <?= $block->escapeHtml(__('Jot us a note and we’ll get back to you as quickly as possible.')) ?> </p> <div class="form__field field"> <label class="field__label" for="name"> <?= $block->escapeHtml(__('Name')) ?> </label> <input class="field__input" name="name" id="name" title="<?= $block->escapeHtmlAttr(__('Name')) ?>" value="<?= $block->escapeHtmlAttr($_helper->getPostValue('name') ?: $_helper->getUserName()) ?>" type="text" data-validate="{ required:true }" > </div> <div class="form__field field"> <label class="field__label" for="email"> <?= $block->escapeHtml(__('Email')) ?> </label> <input class="field__input" id="email" type="email" name="email" title="<?= $block->escapeHtmlAttr(__('Email')) ?>" value="<?= $block->escapeHtmlAttr($_helper->getPostValue('email') ?: $_helper->getUserEmail()) ?>" data-validate="{ required:true, 'validate-email':true }" > </div> Refactored + formatted + BEM <div class="form__field field"> <label class="field__label" for="telephone"> <?= $block->escapeHtml(__('Phone Number')) ?> </label> <input class="field__input" name="telephone" id="telephone" title="<?= $block->escapeHtmlAttr(__('Phone Number')) ?>" value="<?= $block->escapeHtmlAttr($_helper->getPostValue('telephone')) ?>" type="text" > </div> <div class="form__field field"> <label class="field__label" for="comment"> <?= $block->escapeHtml(__('What’s on your mind?')) ?> </label> <textarea class="field__input field__input--textarea" id="comment" name="comment" title="<?= $block->escapeHtmlAttr(__('What’s on your mind?')) ?>" cols="5" rows="3" data-validate="{ required:true }" ><?= $block->escapeHtml($_helper->getPostValue('comment')) ?></textarea> </div> <?= $block->getChildHtml('form.additional.info'); ?> <div class="form__actions actions-toolbar"> <div class="actions-toolbar__primary"> <input class="form__hidden" type="hidden" name="hideit" value="" > <button class="actions-toolbar__button button" title="<?= $block->escapeHtmlAttr(__('Submit')) ?>" type="submit" > <?= $block->escapeHtml(__('Submit')) ?> </button> </div> </div> </form>
  • 19.
    Source - Refactored HTMLelements count 31 - 19 CSS Class count 36 (20 unique) - 27 (15 unique)
  • 20.
    <form class="form contact"> <fieldsetclass="fieldset"> <legend class="legend"> <span></span> </legend> <br /> <div class="field note no-label"></div> <div class="field name required"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text"/> </div> </div> <div class="field email required"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text"/> </div> </div> <div class="field telephone"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text" /> </div> </div> <div class="field comment required"> <label class="label" for="comment"> <span></span> </label> <div class="control"> <textarea class="input-text"></textarea> </div> </div> </fieldset> <div class="actions-toolbar"> <div class="primary"> <input /> <button class="action submit primary"> <span></span> </button> </div> </div> </form> <form class="form"> <h2 class="form__header"></h2> <p class="form__description"></p> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <textarea class="field__input field__input--textarea"></textarea> </div> <div class="form__actions actions-toolbar"> <div class="actions-toolbar__primary"> <input class="form__hidden"> <button class="actions-toolbar__button button"></button> </div> </div> </form>
  • 21.
    <form class="form contact"> <fieldsetclass="fieldset"> <legend class="legend"> <span></span> </legend> <br /> <div class="field note no-label"></div> <div class="field name required"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text"/> </div> </div> <div class="field email required"> <label class="label"> <span></span> </label> <div class="control"> <input class="input-text"/> </div> </div>
  • 22.
    <div class="field telephone"> <labelclass="label"> <span></span> </label> <div class="control"> <input class="input-text" /> </div> </div> <div class="field comment required"> <label class="label" for="comment"> <span></span> </label> <div class="control"> <textarea class="input-text"></textarea> </div> </div> </fieldset> <div class="actions-toolbar"> <div class="primary"> <input /> <button class="action submit primary"> <span></span> </button> </div> </div> </form>
  • 23.
    <form class="form"> <h2 class="form__header"></h2> <pclass="form__description"></p> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <input class="field__input"> </div> <div class="form__field field"> <label class="field__label"></label> <textarea class="field__input field__input--textarea"></textarea> </div> <div class="form__actions actions-toolbar"> <div class="actions-toolbar__primary"> <input class="form__hidden"> <button class="actions-toolbar__button button"></button> </div> </div> </form>
  • 24.
  • 25.
    Magento UI
 It shouldto provide ready to use components, not only set of (little bit overcomplicated) mixins.
  • 26.
    Rebuild „Blank” theme
 UsingMagento UI and our development methodology
  • 27.
    Improve Frontools 100% replacementof CLI methods related to front-end work
  • 28.
  • 30.
    We need somehelp! Specify 3 points of pain in M2 and send them at bartek.igielski@snow.dog Plase be specifyc! I.e. saying just „lack of documentation” sucks. Specify what part of app need (better) docs.
  • 31.
    How to stayupdated? Twitter @Igloczek <- it’s me :) @SnowdogApps <- Snowdog (you don’t say!) GitHub https://github.com/SnowdogApps/magento2-theme-blank-sass https://github.com/SnowdogApps/magento2-frontools Magento Forums https://community.magento.com/t5/Less-to-Sass-Community-Project/bd-p/less-to-sass
  • 32.
    Q & ATime! Let’s stay in touch: Twitter: @igloczek Blog: iglo.tech bartek.igielski@snow.dog