Skip to content

Latest commit

 

History

History
527 lines (414 loc) · 16.2 KB

code-standard-demarcation.md

File metadata and controls

527 lines (414 loc) · 16.2 KB
group subgroup landing-page title menu_title menu_order functional_areas
coding-standards
01_Coding standards
Coding standards
Code demarcation standard
Code demarcation standard
1
Standards

Magento core developers must follow the Magento code demarcation standard.

This standard is recommended for third-party {% glossarytooltip 55774db9-bf9d-40f3-83db-b10cc5ae3b68 %}extension{% endglossarytooltip %} developers.

Some parts of Magento 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:

  • Decouple visual (CSS) layer from the functional (JavaScript) layer.
  • Decouple functional (JavaScript) layer from the {% glossarytooltip 8f407f13-4350-449b-9dc5-217dcf01bc42 %}markup{% endglossarytooltip %} (HTML).
  • Reinstate emphasis on using of {% glossarytooltip 5bfa8a8e-6f3e-4fed-a43e-62339916f02e %}jQuery{% endglossarytooltip %} templates.
  • Reinstate emphasis on decoupling HTML, {% glossarytooltip 6c5cb4e9-9197-46f2-ba79-6147d9bfe66d %}CSS{% endglossarytooltip %} and JS from {% glossarytooltip bf703ab1-ca4b-48f9-b2b7-16a81fd46e02 %}PHP{% endglossarytooltip %} classes.

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

Semantics

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

  • Helps simplify and unify naming conventions that are used to apply visual styles to page elements.

Acceptable {% highlight html %}

...

...

Scroll to text {% endhighlight %}

Unacceptable {% highlight html %}

...

...

...

...

Scroll to text {% endhighlight %}

Semantic representation may rely on ID attribute

  • Forces engineers to think about reusable page components instead of unique singleton components.
  • Reduces long-term maintenance efforts.

Acceptable {% glossarytooltip ae0f1f68-c466-4189-88fd-6cd8b23c804f %}PHTML{% endglossarytooltip %} template

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

{% highlight html %}
  • button 1
  • button 2
  • button 3
Enter text <textarea id="some-id"></textarea>
Scroll to text {% endhighlight %}

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

{% highlight html %}
  • button 1
  • button 2
  • button 3
{% endhighlight %}

JavaScript file

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

CSS file {% highlight css %} #my-special-menu { ... } #my-special-menu > li { ... } {% endhighlight %}

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:

  • logic
  • information
  • data
  • model
  • outline
  • message

Presentation includes:

  • aesthetic
  • graphics
  • design
  • style
  • visualization
  • view

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

Acceptable:

{%highlight html%}

HTML has been created to semantically represent documents.

Warning: Following the procedure described below may irreparably damage your equipment.

{%endhighlight%}

Unacceptable:

{%highlight html%}

HTML has been created to semantically represent documents.

Warning: Following the procedure described below may irreparably damage your equipment.

{%endhighlight%}

Code demarcation

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 {% glossarytooltip a2aff425-07dd-4bd6-9671-29b7edefa871 %}HTML{% endglossarytooltip %} class attributes. In case this option is not applicable then it is recommended to use HTML tags and form element's type attribute.

  • Enforces clean, strict separation between visual and business logic layers.
  • Allows {% glossarytooltip b00459e5-a793-44dd-98d5-852ab33fc344 %}frontend{% endglossarytooltip %} and {% glossarytooltip 74d6d228-34bd-4475-a6f8-0c0f4d6d0d61 %}backend{% endglossarytooltip %} teams to work independently.
  • Allows changing look and feel without affecting business functionality, and vice versa.
  • Enables frontend teams to clean up old styles quickly and easily when refactoring.

Acceptable CSS selectors

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

Unacceptable CSS selectors

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

You must not hard-code CSS styles in JavaScript files

{: .bs-callout .bs-callout-info } Exception: CSS attributes where values must be calculated beyond the css-topics/LESS code.

  • Simplifies change of the default look and feel by adding CSS classes to and removing them from elements.
  • Improves style extensibility.
  • Reduces long-term maintenance efforts by containing CSS styles in a single place.

Acceptable {% glossarytooltip 312b4baf-15f7-4968-944e-c814d53de218 %}JavaScript{% endglossarytooltip %} {% glossarytooltip f0dcf847-ce21-4b88-8b45-83e1cbf08100 %}widget{% endglossarytooltip %} file {% highlight javascript %} ... 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'}) ... {% endhighlight %}

Unacceptable JavaScript file

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

You must not use inline CSS styles inside HTML tags

  • Improves style extensibility allowing engineers to overload styles easier by toggling classes.
  • Enforces clean, strict separation between visual presentation and markup.
  • Enables frontend teams quickly and easily clean up old styles.

Acceptable PHTML template

{% highlight html %}

...
{% endhighlight %}

Unacceptable PHTML template

{% highlight html %}

...
{% endhighlight %}

Business logic and JavaScript

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

  • Enforces clean, strict separation between visual and business logic layers.
  • Allows frontend and backend teams to work independently.
  • Allows changing business logic without affecting styling and vice versa.

Acceptable PHTML template

{% highlight html %}

More details
{% endhighlight %}

Acceptable JavaScript file

{% highlight javascript %} 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 ... {% endhighlight %}

Unacceptable PHTML file

{% highlight html %}

{% endhighlight %}

Unacceptable JavaScript file

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

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

{% highlight html %}

Content
Content
Content
Content
{% endhighlight %}

Unacceptable

{% highlight html %}

Content
Content
Content
Content
{% endhighlight %}

You must not select DOM elements based on HTML structure

  • Allows frontend teams to modify markup and themes without affecting business logic.

Acceptable JavaScript file

{% highlight javascript %} this.element.find('[data-action="edit"]'); this.elements.closest('[data-container]'); {% endhighlight %}

Unacceptable JavaScript file

{% highlight javascript %} this.element.children().children().html('hello world'); this.element.parent().find('[data-action="edit"]').data('entity_id'); {% endhighlight %}

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

  • Reinstates emphasis on jQuery templates. For more information, see JavaScript Coding Best Practices.
  • Reduces long-term maintenance efforts by having markup code stored in one place.
  • Simplifies frontend debugging efforts.

You must not hard-code inline JavaScript in PHP classes

  • Reduces long term maintenance by having frontend business logic stored in one place.
  • Reduces the number of files to be modified.

Acceptable PHP file

{% highlight php startinline=true %} ... public function getSelectorOptions() { return $selectorOptions; } ... {% endhighlight %}

Acceptable PHTML template

{% highlight php startinline=true %} ...

... {% endhighlight %}

or

Acceptable PHTML template

{% highlight php startinline=true %} ...

<script type="text/x-magento-init"> { "[data-role='treeSuggest']": { "treeSuggest": getSelectorOptions(); ?> } } </script> ... {% endhighlight %}

Unacceptable PHP file

{% highlight php startinline=true %} ... public function getAfterElementHtml() { return <<<HTML

<script> jQuery('#{$htmlId}-suggest').treeSuggest({$selectorOptions}); </script>

... {% endhighlight %}

Unacceptable PHTML template

{% highlight php startinline=true %}

getAfterElementHtml(); ?>

{% endhighlight %}

PHTML templates and PHP files

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

  • Reduces long-term maintenance efforts by having styles stored in one place.
  • Simplifies debugging and reduces number of files to be modified.
  • Makes styles more extensible and easier to override when needed.

Acceptable PHP file

{% highlight php startinline=true %} ... $fieldset->addField('new_category_parent', 'text', array( 'label' => Mage::helper('Mage_Catalog_Helper_Data')->('Parent Category'), 'title' => Mage::helper('Mage_Catalog_Helper_Data')->('Parent Category'), 'required' => true, 'class' => 'parent category', )); ... {% endhighlight %}

Unacceptable PHP file

{% highlight php startinline=true %} ... $fieldset->addField('new_category_parent', 'text', array( 'label' => Mage::helper('Mage_Catalog_Helper_Data')->('Parent Category'), 'title' => Mage::helper('Mage_Catalog_Helper_Data')->('Parent Category'), 'required' => true, 'style' => 'border: 1px solid #ccc;', )); ... {% endhighlight %}

You must not hard-code inline JavaScript in PHP classes

  • Reduces long term maintenance by having frontend business logic stored in one place.
  • Reduces the number of files to be modified.

Acceptable PHP file

{% highlight php startinline=true %} ... public function getSelectorOptions() { return $selectorOptions; } ... {% endhighlight %}

Acceptable PHTML template

{% highlight php startinline=true %} ...

... {% endhighlight %}

Unacceptable PHP file

{% highlight php startinline=true %} ... public function getAfterElementHtml() { return <<<HTML

<script> jQuery('#{$htmlId}-suggest').treeSuggest({$selectorOptions}); </script>

... {% endhighlight %}

Unacceptable PHTML template {% highlight php startinline=true %}

getAfterElementHtml(); ?>

{% endhighlight %}

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

  • Reduces long-term maintenance efforts by having markup stored in one place.
  • Reduces the number of files to be modified.

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

{% highlight php startinline=true %} <input type="checkbox" getAttributeName($element)) ? ' name="' . $this->getAttributeName($element) . '"' : NULL; ?> data-mage-init="{customToggleWidget: [elementSelector: "input[name='someCustomName']"]}" />

__('Change'); ?>

{% endhighlight %}

Unacceptable PHP file

{%highlight php%} ... 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; } ... {%endhighlight%}

Unacceptable PHTML template

{%highlight php%} getCheckbox($element)?> __('Change'); ?>

{%endhighlight%}