Code demarcation standard

Core developers must follow the code demarcation standard.

This standard is recommended for third-party extension developers.

Some parts of code might not comply with the standard, but we are working to gradually improve this.

The standard was developed in the scope of our efforts to ensure the following:

Use RFC 2119 to interpret the "MUST," "MUST NOT," "REQUIRED," "SHALL," "SHALL NOT," "SHOULD," "SHOULD NOT," "RECOMMENDED," "MAY," and "OPTIONAL" keywords.

Semantics

Attribute names and values

For attribute names and values you must use meaningful unabbreviated lowercase words comprised of Latin characters concatenated with a hyphen (-)

Acceptable:

<section id="information-dialog-tree">
   <p> ... </p>
   <p> ... </p>
</section>
<a href="#information-dialog-tree">Scroll to text</a>

Unacceptable:

<section id="some_id">
   <p> ... </p>
   <p> ... </p>
</section>
<section id="some_id">
   <p> ... </p>
   <p> ... </p>
</section>
<a href="#some_id">Scroll to text</a>

Attribute IDs

Semantic representation may rely on ID attribute

Acceptable PHTML template:

The following acceptable example is terse and uses an Accessible Rich Internet Applications (ARIA) approach.

<ul>
   <li class="first" type="button" aria-pressed="false" aria-controls="some-id">button 1</li>
   <li type="button" aria-pressed="false" aria-controls="some-id">button 2</li>
   <li type="button" aria-pressed="true" aria-controls="some-id">button 3</li>
</ul>
<div>
   <label for="some-id">Enter text</label>
   <textarea id="some-id"></textarea>
</div>
<a href="#some-id">Scroll to text</a>

Unacceptable combination of PHTML, JavaScript, and CSS files:

The following unacceptable example replaces a single PHTML file with a combination of a PHTML, JavaScript, and CSS files.

PHTML file:

<ul id="my-special-menu">
   <li id="buttonId1" class="first" type="button">button 1</li>
   <li id="buttonId2" type="button">button 2</li>
   <li id="buttonId3" type="button">button 3</li>
</ul>

JavaScript file:

$('#my-special-menu').on('click','li[id^="button"]', function() { ... })

CSS file:

#my-special-menu { ... }
#my-special-menu > li { ... }

Presentation and content

You must follow the separation of presentation and content methodology

The following list will help you make a distinction between the actual meaning of a document, and how this meaning is presented to its readers:

Content (Semantics) includes:

Presentation includes:

HTML markup

You must use semantic HTML markup only, and must not use presentation markup

Acceptable:

<p>HTML has been created to <strong>semantically</strong> represent documents.</p>
<p><strong>Warning:</strong> Following the procedure described below may irreparably damage your equipment.</p>

Unacceptable:

<p>HTML has been created to <b>semantically</b> represent documents.</p>
<p><b>Warning:</b> Following the procedure described below may irreparably damage your equipment.</p>

Code demarcation

Visual representation

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).

As the first option, you are required to use HTML class attributes. In case this option is not applicable then it is recommended to use HTML tags and form element's type attribute.

Acceptable CSS selectors:

.notices-wrapper { ... }
.page-header:after { ... }
.payment-list:first-child { ... }
.caution { ... }
.caution.link { ... }
form input[type="password"] { ... }
.control-text:focus { ... }
a:hover { ... }
nav li._active { ... }

Unacceptable CSS selectors:

#header { ... }
[data-action="delete"] { ... }
form input[name="password"] { ... }
section[role="main"] { ... }
[role="menu"] [role="menuitem"] { ... }
[role="menu"] [role="menuitem"].active { ... }

Hard-coded CSS styles

You must not hard-code CSS styles in JavaScript files

Exception: CSS attributes where values must be calculated beyond the css-topics/LESS code.

Acceptable JavaScript widget file:

...
   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'});
...

Unacceptable JavaScript file:

this.element.on('click', function() {
   if ($(this).is(':visible')) {
      $(this).css({ visibility: 'hidden' });
   } else {
      $(this).css({ visibility: 'visible' });
   }
});

Inline CSS styles

You must not use inline CSS styles inside HTML tags

Acceptable PHTML template:

<div class="no-display"> ... </div>

Unacceptable PHTML template:

<div style="display: none;"> ... </div>

Business logic and JavaScript

Business logic must rely on only the form, form element name attributes, or data attributes

Acceptable PHTML template:

<div data-action="delete" data-mage-init="{myWidget: [option1: 'string']}"></div>
<div data-role="tooltip">More details</div>

Acceptable JavaScript file:

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
...

Unacceptable PHTML file:

<div id="my-widget"></div>

Unacceptable JavaScript file:

$('#my-widget').doSomething();
$('.parent').on('click', '.button', function() { ... });
$('form').validate();
$('[role="menu"]').navigation();

HTML helper classes

You must assign HTML helper classes in JavaScript to modify presentation layer

HTML helper class names added in JavaScript REQUIRE underscore symbol ("_") at the beginning and must be written in lowercase.

Acceptable:

<div class="tab-element _active">Content</div>
<div class="sales-transactions _open">Content</div>
<div class="billing-agreement _expanded">Content</div>
<div class="sales-report _hidden">Content</div>

Unacceptable:

<div class="tab-element active">Content</div>
<div class="sales-transactions open">Content</div>
<div class="billing-agreement expanded">Content</div>
<div class="sales-report hidden">Content</div>

DOM elements

You must not select DOM elements based on HTML structure

Acceptable JavaScript file:

this.element.find('[data-action="edit"]');
this.elements.closest('[data-container]');

Unacceptable JavaScript file:

this.element.children().children().html('hello world');
this.element.parent().find('[data-action="edit"]').data('entity_id');

jQuery templates

You must use jQuery templates to insert recurring markup into DOM structure

PHTML templates and PHP files

Hard-coded CSS styles

You must not hard-code inline CSS styles in PHP classes

Acceptable PHP file:

...
$fieldset->addField('new_category_parent', 'text', [
    'label'    => __('Parent Category'),
    'title'    => __('Parent Category'),
    'required' => true,
    'class'    => 'parent category',
]);
...

Unacceptable PHP file:

...
$fieldset->addField('new_category_parent', 'text', [
    'label'    => __('Parent Category'),
    'title'    => __('Parent Category'),
    'required' => true,
    'style'    => 'border: 1px solid #ccc;',
]);
...

Inline JavaScript

You must not hard-code inline JavaScript in PHP classes

Acceptable PHP file:

...
public function getSelectorOptions()
{
    return $selectorOptions;
}
...

Acceptable PHTML template:

...
<div data-mage-init="{treeSuggest: [<?php echo $this->getSelectorOptions(); ?>]}"></div>
...

or

Acceptable PHTML template:

...
<div data-role="treeSuggest"></div>
<script type="text/x-magento-init">
{
    "[data-role='treeSuggest']": {
        "treeSuggest": <?php echo $this->getSelectorOptions(); ?>
    }
}
</script>
...

Unacceptable PHP file:

...
public function getAfterElementHtml()
{
    return <<<HTML
<script>
jQuery('#{$htmlId}-suggest').treeSuggest({$selectorOptions});
</script>
...

Unacceptable PHTML template:

<?php echo $this->getAfterElementHtml(); ?>

HTML markup

You must not hard-code HTML markup (used in the <body> tag) in PHP classes

Acceptable PHP file:

...
public function getAttributeName($element)
{
    return ($element->getExtType() === 'multiple') ? $element->getId() . '_checkbox' : NULL;
}

public function getAttributeId($element)
{
    return $element->getId();
}
...

Acceptable PHTML template:

<span class="attribute-change-checkbox">
<label>
   <input type="checkbox"
      <?php echo ($this->getAttributeName($element)) ? ' name="' . $this->getAttributeName($element) . '"' : NULL; ?>
      data-mage-init="{customToggleWidget: [elementSelector: "input[name='someCustomName']"]}" />
   <?php echo __('Change'); ?>
</label>
</span>
<!-- jQuery.hide() code can be either located in the widget itself OR can ask PHP Block class whether or not 'weight_and_type_switcher' should be visible. Based on this condition CSS can be applied to hide/show those elements. -->

Unacceptable PHP file:

...
public function getCheckbox($elementName){
    $elementNameTag = $this->getAttributeName($elementName) ? 'name="' . $this->getAttributeName($elementName) . '"' : NULL;
    $tpl = "<input type=\"checkbox\" {$elementNameTag} data-mage-init=\"{customToggleWidget: [elementSelector: \"input[name='someCustomName']\"]}\" />";
    return $tpl;
}
...

Unacceptable PHTML template:

<span class="attribute-change-checkbox">
   <label>
      <?php echo $this->getCheckbox($element)?>
      <?php echo __('Change'); ?>
   </label>
</span>
<!-- jQuery.hide() code can be either located in the widget itself OR can ask PHP Block class whether or not 'weight_and_type_switcher' should be visible. Based on this condition CSS can be applied to hide/show those elements. -->