SlideShare a Scribd company logo
1 of 29
Типичные ошибки при кастомизации Magento 2 и как
их избежать
Спикер: Влад Веселов
/me
2
Vlad
https://github.com/orlangur
Extend core classes in
order to change behavior
3
http://fabien.potencier.org/pragmatism-over-theory-protected-vs-private.html
https://ocramius.github.io/blog/when-to-declare-classes-final/
Many method are private, copy-paste is lesser evil
Extend core classes in
order to add behavior
4
Do not increase core classes responsibility
Bad: inheritance
5
class AbstractController extends Action
{
// ...
protected function validate(
$request
) {}
protected function generateHash(
$request
) {}
}
class Edit extends AbstractController
{
public function execute()
{
$errors = $this->validate(
$request
);
// ...
$hash = $this->generateHash(
$request
);
// ...
}
}
// Smaller classes, one responsibility, more flexible,
easy to understand, more testable.
Good: composition
6
class Edit extends Action
{
public function __constructor(
ValidatorInterface $validator,
HashGeneratorInterface $hashGenerator
) {}
public function execute()
{
$errors = $this->validator-
>validate($request);
// ...
$hash = $this->hashGenerator-
>generateHash($request);
}
}
Entity management - EntityManager?
7
namespace MagentoFrameworkEntityManager;
/**
* It's not recommended to use EntityManager and its infrastructure for your entities persistence.
* In the nearest future new Persistence Entity Manager would be released which will cover all the requirements for
* persistence layer along with Query API as performance efficient APIs for Read scenarios.
* Currently, it's recommended to use Resource Model infrastructure and make a successor of
* MagentoFrameworkModelResourceModelDbAbstractDb class or successor of
* MagentoEavModelEntityAbstractEntity if EAV attributes support needed.
*
* For filtering operations, it's recommended to use successor of
* MagentoFrameworkModelResourceModelDbCollectionAbstractCollection class.
*/
class EntityManager
{
Extend core entity
8
Steps to reproduce
1. Create a custom module that add a field to quote and sales_order table
2. Update the field in quote table and then place an order
Expected result
1. The field value will get copied to the order table
Actual result
1. The field does not get copy over to sales_order table
https://github.com/magento/magento2/issues/5823
Extend @api interface with own
fields
9
You don’t need it, really
Extend @api interface with core
fields
10
Sometimes it may be valid but please don’t blindly fill a GitHub issue each time you meet
such situation
11
The standard was developed in the scope of our efforts to ensure the following:
• Decouple visual (CSS) layer from the functional (JavaScript) layer.
• Decouple functional (JavaScript) layer from the markup (HTML).
• Reinstate emphasis on using of jQuery templates.
• Reinstate emphasis on decoupling HTML, CSS and JS from PHP classes.
http://devdocs.magento.com/guides/v2.0/coding-standards/code-standard-demarcation.html
Code demarcation standard
Visual representation must rely only on
HTML class attributes, CSS pseudo-classes
and pseudo-elements, HTML tags, and form
element’s type attribute and form elements
state attributes (example: disabled, checked)
12
Bad
13
#header { ... }
[data-action="delete"] { ... }
form input[name="password"] { ... }
section[role="main"] { ... }
[role="menu] [role="menuitem"] { ... }
[role="menu] [role="menuitem"].active { ... }
Good
14
.notices-wrapper { ... }
.page-header:after { ... }
.payment-list:first-child { ... }
.caution { ... }
.caution.link { ... }
form input[type="password"] { ... }
.control-text:focus { ... }
a:hover { ... }
nav li._active { ... }
You must not hard-code CSS styles
in JavaScript files
15
Bad
16
this.element.on('click', function() {
if ($(this).is(':visible')) {
$(this).css({ visibility: 'hidden' });
} else {
$(this).css({ visibility: 'visible' });
}
});
Good
17
...
options: {
hOffset: 0,
myCustomElement: '[data-container="my-custom-element"]',
hiddenClass: '_hidden'
}
...
this.element.toggleClass(this.options.hiddenClass);
...
this.options.hOffset = /* calculation based on dimensions of some DOM elements within a widget */
this.element.find(this.options.myCustomElement).css({'margin-top', this.options.hOffset + 'px'})
...
You must not use inline CSS styles
inside HTML tags
18
Bad
19
<div style="display: none;"> ... </div>
Good
20
<div class="no-display"> ... </div>
Business logic must rely on only the form,
form element name attributes, or data attributes
21
Good
22
<div id="my-widget"></div>
$('#my-widget').doSomething();
$('.parent').on('click', '.button', function() { ... });
$('form').validate();
$('[role="menu"]').navigation();
Actually, bad
23
<div id="my-widget"></div>
$('#my-widget').doSomething();
$('.parent').on('click', '.button', function() { ... });
$('form').validate();
$('[role="menu"]').navigation();
Really Good
24
<div data-action="delete" data-mage-init="{myWidget: [option1: 'string']}"></div>
<div data-role="tooltip">More details</div>
options {
deleteAction: '[data-action="delete"]',
tooltip: '[data-role="tooltip]'
}
...
this.element.find(this.options.deleteAction).on( ... );
this.element.on('click', this.options.deleteAction , function() { ... });
...
// Globally initialized widgets
$( this.options.tooltip).tooltip(); // Globally for ALL tooltip elements
...
You must not select DOM elements
based on HTML structure
25
Bad
26
this.element.children().children().html('hello world');
this.element.parent().find('[data-action="edit"]').data('entity_id');
Good
27
this.element.find('[data-action="edit"]');
this.elements.closest(‘[data-container]');
Don't use (arbitrary) core
code for reference
28
Спасибо за внимание!

More Related Content

What's hot

Desenvolvimento web com Ruby on Rails (parte 6)
Desenvolvimento web com Ruby on Rails (parte 6)Desenvolvimento web com Ruby on Rails (parte 6)
Desenvolvimento web com Ruby on Rails (parte 6)
Joao Lucas Santana
 
Twitter bootstrap
Twitter bootstrapTwitter bootstrap
Twitter bootstrap
dennisdc
 

What's hot (20)

The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
DJango admin interface
DJango admin interfaceDJango admin interface
DJango admin interface
 
Understanding form helpers
Understanding form helpersUnderstanding form helpers
Understanding form helpers
 
Going with style: Themes and apps for Magento Go
Going with style: Themes and apps for Magento GoGoing with style: Themes and apps for Magento Go
Going with style: Themes and apps for Magento Go
 
Spout - Building a RESTful web app with Angular.js and BEAR.Sunday
Spout - Building a RESTful web app with Angular.js and BEAR.SundaySpout - Building a RESTful web app with Angular.js and BEAR.Sunday
Spout - Building a RESTful web app with Angular.js and BEAR.Sunday
 
Jsf
JsfJsf
Jsf
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
Beyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance JavascriptBeyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance Javascript
 
Ch9 .Best Practices for Class-Based Views
Ch9 .Best Practices  for  Class-Based ViewsCh9 .Best Practices  for  Class-Based Views
Ch9 .Best Practices for Class-Based Views
 
Java Server Faces
Java Server FacesJava Server Faces
Java Server Faces
 
Django Bogotá. CBV
Django Bogotá. CBVDjango Bogotá. CBV
Django Bogotá. CBV
 
Desenvolvimento web com Ruby on Rails (parte 6)
Desenvolvimento web com Ruby on Rails (parte 6)Desenvolvimento web com Ruby on Rails (parte 6)
Desenvolvimento web com Ruby on Rails (parte 6)
 
Django Templates
Django TemplatesDjango Templates
Django Templates
 
Twitter bootstrap
Twitter bootstrapTwitter bootstrap
Twitter bootstrap
 
Jinja2 Templates - San Francisco Flask Meetup
Jinja2 Templates - San Francisco Flask MeetupJinja2 Templates - San Francisco Flask Meetup
Jinja2 Templates - San Francisco Flask Meetup
 
Odoo Experience 2018 - Develop an App with the Odoo Framework
Odoo Experience 2018 - Develop an App with the Odoo FrameworkOdoo Experience 2018 - Develop an App with the Odoo Framework
Odoo Experience 2018 - Develop an App with the Odoo Framework
 
Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5
 
Django class based views for beginners
Django class based views for beginnersDjango class based views for beginners
Django class based views for beginners
 
Pengenalan AngularJS
Pengenalan AngularJSPengenalan AngularJS
Pengenalan AngularJS
 
Grain final border one
Grain final border oneGrain final border one
Grain final border one
 

Similar to Typical customization pitfalls in Magento 2

Extending and Customizing Open Atrium
Extending and Customizing Open AtriumExtending and Customizing Open Atrium
Extending and Customizing Open Atrium
Nuvole
 

Similar to Typical customization pitfalls in Magento 2 (20)

Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
Simple module Development in Joomla! 2.5
Simple module Development in Joomla! 2.5Simple module Development in Joomla! 2.5
Simple module Development in Joomla! 2.5
 
Mini-Training: Javascript Patterns
Mini-Training: Javascript PatternsMini-Training: Javascript Patterns
Mini-Training: Javascript Patterns
 
PHPConf-TW 2012 # Twig
PHPConf-TW 2012 # TwigPHPConf-TW 2012 # Twig
PHPConf-TW 2012 # Twig
 
lecture5
lecture5lecture5
lecture5
 
lecture5
lecture5lecture5
lecture5
 
Empowering users: modifying the admin experience
Empowering users: modifying the admin experienceEmpowering users: modifying the admin experience
Empowering users: modifying the admin experience
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Django Vs Rails
Django Vs RailsDjango Vs Rails
Django Vs Rails
 
Building Potent WordPress Websites
Building Potent WordPress WebsitesBuilding Potent WordPress Websites
Building Potent WordPress Websites
 
Styling Components with JavaScript: MelbCSS Edition
Styling Components with JavaScript: MelbCSS EditionStyling Components with JavaScript: MelbCSS Edition
Styling Components with JavaScript: MelbCSS Edition
 
From framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytvFrom framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytv
 
Introduction to Magento 2 module development - PHP Antwerp Meetup 2017
Introduction to Magento 2 module development - PHP Antwerp Meetup 2017Introduction to Magento 2 module development - PHP Antwerp Meetup 2017
Introduction to Magento 2 module development - PHP Antwerp Meetup 2017
 
D7 theming what's new - London
D7 theming what's new - LondonD7 theming what's new - London
D7 theming what's new - London
 
Comparison of different access controls
Comparison of different access controlsComparison of different access controls
Comparison of different access controls
 
Extending and Customizing Open Atrium
Extending and Customizing Open AtriumExtending and Customizing Open Atrium
Extending and Customizing Open Atrium
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101
 
«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​
 

More from Magecom UK Limited

More from Magecom UK Limited (20)

Magento Meetup #12. Alex Shkurko.pptx
Magento Meetup #12. Alex Shkurko.pptxMagento Meetup #12. Alex Shkurko.pptx
Magento Meetup #12. Alex Shkurko.pptx
 
Magento Meetup #12 Anastasiia Bondar
Magento Meetup #12 Anastasiia BondarMagento Meetup #12 Anastasiia Bondar
Magento Meetup #12 Anastasiia Bondar
 
Magento Meetup #12 Vlad Opukhlyi
Magento Meetup #12 Vlad OpukhlyiMagento Meetup #12 Vlad Opukhlyi
Magento Meetup #12 Vlad Opukhlyi
 
Google Page Insights and Magento 2 — Sergey Nezbritskiy | Magento Meetup Onli...
Google Page Insights and Magento 2 — Sergey Nezbritskiy | Magento Meetup Onli...Google Page Insights and Magento 2 — Sergey Nezbritskiy | Magento Meetup Onli...
Google Page Insights and Magento 2 — Sergey Nezbritskiy | Magento Meetup Onli...
 
Magento NodeJS Microservices — Yegor Shytikov | Magento Meetup Online #11
Magento NodeJS Microservices — Yegor Shytikov | Magento Meetup Online #11Magento NodeJS Microservices — Yegor Shytikov | Magento Meetup Online #11
Magento NodeJS Microservices — Yegor Shytikov | Magento Meetup Online #11
 
Magento enhanced media gallery - Alexander Shkurko
Magento enhanced media gallery - Alexander ShkurkoMagento enhanced media gallery - Alexander Shkurko
Magento enhanced media gallery - Alexander Shkurko
 
7 ошибок одного Black Friday - Влад Опухлый
7 ошибок одного Black Friday - Влад Опухлый7 ошибок одного Black Friday - Влад Опухлый
7 ошибок одного Black Friday - Влад Опухлый
 
Magento & Cloud - Korostelov Avexey
Magento & Cloud - Korostelov AvexeyMagento & Cloud - Korostelov Avexey
Magento & Cloud - Korostelov Avexey
 
Making the Magento 2 Javascript Loading Great Again - Robin van Raan
Making the Magento 2 Javascript Loading Great Again - Robin van RaanMaking the Magento 2 Javascript Loading Great Again - Robin van Raan
Making the Magento 2 Javascript Loading Great Again - Robin van Raan
 
Deep Dive in Magento DI
Deep Dive in Magento DIDeep Dive in Magento DI
Deep Dive in Magento DI
 
From Repositories to Commands - Alexander Shkurko
From Repositories to Commands - Alexander Shkurko From Repositories to Commands - Alexander Shkurko
From Repositories to Commands - Alexander Shkurko
 
Advanced GIT or How to Change the History
Advanced GIT  or How to Change the HistoryAdvanced GIT  or How to Change the History
Advanced GIT or How to Change the History
 
MSI In-Store Pickup Функционал & сложности
MSI In-Store Pickup Функционал & сложностиMSI In-Store Pickup Функционал & сложности
MSI In-Store Pickup Функционал & сложности
 
Adobe Stock Integration community project
Adobe Stock Integration community projectAdobe Stock Integration community project
Adobe Stock Integration community project
 
Proof of Concept for Magento 2 Projects: Occamo’s Razor
Proof of Concept for Magento 2 Projects: Occamo’s RazorProof of Concept for Magento 2 Projects: Occamo’s Razor
Proof of Concept for Magento 2 Projects: Occamo’s Razor
 
Что нужно знать девелоперу о SEO на этапе проектирования сайта
Что нужно знать девелоперу о SEO на этапе проектирования сайтаЧто нужно знать девелоперу о SEO на этапе проектирования сайта
Что нужно знать девелоперу о SEO на этапе проектирования сайта
 
Magento-сертификация: инструкция по применению и как это было
Magento-сертификация: инструкция по применению и как это былоMagento-сертификация: инструкция по применению и как это было
Magento-сертификация: инструкция по применению и как это было
 
Experience in Magento Community Projects
Experience in Magento Community ProjectsExperience in Magento Community Projects
Experience in Magento Community Projects
 
UI components: synergy of backend and frontend
UI components: synergy of backend and frontendUI components: synergy of backend and frontend
UI components: synergy of backend and frontend
 
MSI - Reservation Challenges with 3rd-party Systems
MSI - Reservation Challenges with 3rd-party SystemsMSI - Reservation Challenges with 3rd-party Systems
MSI - Reservation Challenges with 3rd-party Systems
 

Recently uploaded

Recently uploaded (20)

AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 

Typical customization pitfalls in Magento 2

  • 1. Типичные ошибки при кастомизации Magento 2 и как их избежать Спикер: Влад Веселов
  • 3. Extend core classes in order to change behavior 3 http://fabien.potencier.org/pragmatism-over-theory-protected-vs-private.html https://ocramius.github.io/blog/when-to-declare-classes-final/ Many method are private, copy-paste is lesser evil
  • 4. Extend core classes in order to add behavior 4 Do not increase core classes responsibility
  • 5. Bad: inheritance 5 class AbstractController extends Action { // ... protected function validate( $request ) {} protected function generateHash( $request ) {} } class Edit extends AbstractController { public function execute() { $errors = $this->validate( $request ); // ... $hash = $this->generateHash( $request ); // ... } } // Smaller classes, one responsibility, more flexible, easy to understand, more testable.
  • 6. Good: composition 6 class Edit extends Action { public function __constructor( ValidatorInterface $validator, HashGeneratorInterface $hashGenerator ) {} public function execute() { $errors = $this->validator- >validate($request); // ... $hash = $this->hashGenerator- >generateHash($request); } }
  • 7. Entity management - EntityManager? 7 namespace MagentoFrameworkEntityManager; /** * It's not recommended to use EntityManager and its infrastructure for your entities persistence. * In the nearest future new Persistence Entity Manager would be released which will cover all the requirements for * persistence layer along with Query API as performance efficient APIs for Read scenarios. * Currently, it's recommended to use Resource Model infrastructure and make a successor of * MagentoFrameworkModelResourceModelDbAbstractDb class or successor of * MagentoEavModelEntityAbstractEntity if EAV attributes support needed. * * For filtering operations, it's recommended to use successor of * MagentoFrameworkModelResourceModelDbCollectionAbstractCollection class. */ class EntityManager {
  • 8. Extend core entity 8 Steps to reproduce 1. Create a custom module that add a field to quote and sales_order table 2. Update the field in quote table and then place an order Expected result 1. The field value will get copied to the order table Actual result 1. The field does not get copy over to sales_order table https://github.com/magento/magento2/issues/5823
  • 9. Extend @api interface with own fields 9 You don’t need it, really
  • 10. Extend @api interface with core fields 10 Sometimes it may be valid but please don’t blindly fill a GitHub issue each time you meet such situation
  • 11. 11 The standard was developed in the scope of our efforts to ensure the following: • Decouple visual (CSS) layer from the functional (JavaScript) layer. • Decouple functional (JavaScript) layer from the markup (HTML). • Reinstate emphasis on using of jQuery templates. • Reinstate emphasis on decoupling HTML, CSS and JS from PHP classes. http://devdocs.magento.com/guides/v2.0/coding-standards/code-standard-demarcation.html Code demarcation standard
  • 12. Visual representation must rely only on HTML class attributes, CSS pseudo-classes and pseudo-elements, HTML tags, and form element’s type attribute and form elements state attributes (example: disabled, checked) 12
  • 13. Bad 13 #header { ... } [data-action="delete"] { ... } form input[name="password"] { ... } section[role="main"] { ... } [role="menu] [role="menuitem"] { ... } [role="menu] [role="menuitem"].active { ... }
  • 14. Good 14 .notices-wrapper { ... } .page-header:after { ... } .payment-list:first-child { ... } .caution { ... } .caution.link { ... } form input[type="password"] { ... } .control-text:focus { ... } a:hover { ... } nav li._active { ... }
  • 15. You must not hard-code CSS styles in JavaScript files 15
  • 16. Bad 16 this.element.on('click', function() { if ($(this).is(':visible')) { $(this).css({ visibility: 'hidden' }); } else { $(this).css({ visibility: 'visible' }); } });
  • 17. Good 17 ... options: { hOffset: 0, myCustomElement: '[data-container="my-custom-element"]', hiddenClass: '_hidden' } ... this.element.toggleClass(this.options.hiddenClass); ... this.options.hOffset = /* calculation based on dimensions of some DOM elements within a widget */ this.element.find(this.options.myCustomElement).css({'margin-top', this.options.hOffset + 'px'}) ...
  • 18. You must not use inline CSS styles inside HTML tags 18
  • 21. Business logic must rely on only the form, form element name attributes, or data attributes 21
  • 22. Good 22 <div id="my-widget"></div> $('#my-widget').doSomething(); $('.parent').on('click', '.button', function() { ... }); $('form').validate(); $('[role="menu"]').navigation();
  • 23. Actually, bad 23 <div id="my-widget"></div> $('#my-widget').doSomething(); $('.parent').on('click', '.button', function() { ... }); $('form').validate(); $('[role="menu"]').navigation();
  • 24. Really Good 24 <div data-action="delete" data-mage-init="{myWidget: [option1: 'string']}"></div> <div data-role="tooltip">More details</div> options { deleteAction: '[data-action="delete"]', tooltip: '[data-role="tooltip]' } ... this.element.find(this.options.deleteAction).on( ... ); this.element.on('click', this.options.deleteAction , function() { ... }); ... // Globally initialized widgets $( this.options.tooltip).tooltip(); // Globally for ALL tooltip elements ...
  • 25. You must not select DOM elements based on HTML structure 25
  • 28. Don't use (arbitrary) core code for reference 28