Nette Documentation Preview

syntax
Coding Standard
***************

This document describes rules and recommendations for developing Nette. When contributing code to Nette, you must follow them. The easiest way how to do it is to imitate the existing code.
The idea is to make all the code look like it was written by one person. .[perex]

Nette Coding Standard corresponds to [PSR-12 Extended Coding Style |https://www.php-fig.org/psr/psr-12/] with two main exceptions: it uses [#tabs instead of spaces] for indentation, and uses [PascalCase for class constants|https://blog.nette.org/en/for-less-screaming-in-the-code].


General Rules
=============

- Every PHP file must contain `declare(strict_types=1)`
- Two empty lines are used to separate methods for better readability.
- The reason for using shut-up operator must be documented: `@mkdir($dir); // @ - directory may exist`
- If weak typed comparison operator is used (ie. `==`, `!=`, ...), the intention must be documented: `// == to accept null`
- You can write more exceptions into one file `exceptions.php`
- The visibility of methods is not specified for interfaces because they are always public.
- Each property, return value, and parameter must have a type specified. On the other hand, for final constants, we never specify the type because it is obvious.
- Single quotes should be used to delimit the string, except when the literal itself contains apostrophes.


Naming Conventions
==================

- Avoid using abbreviations unless the full name is excessive.
- Use uppercase for two-letter abbreviations, and pascal/camel case for longer abbreviations.
- Use a noun or noun phrase for class name.
- Class names must contain not only specificity (`Array`) but also generality (`ArrayIterator`). The exception are PHP attributes.
- "Class constants and enums should use PascalCaps":https://blog.nette.org/en/for-less-screaming-in-the-code.
- "Interfaces and abstract classes should not contain prefixes or postfixes":https://blog.nette.org/en/prefixes-and-suffixes-do-not-belong-in-interface-names like `Abstract`, `Interface` or `I`.


Wrapping and Braces
===================

Nette Coding Standard corresponds to PSR-12 (or PER Coding Style), in some points it specifies it more or modifies it:

- arrow functions are written without a space before the parenthesis, i.e. `fn($a) => $b`
- no empty line is required between different types of `use` import statements
- the return type of a function/method and the opening curly bracket are always on separate lines:

```php
	public function find(
		string $dir,
		array $options,
	): array
	{
		// method body
	}
```

The opening curly bracket on a separate line is important for visually separating the function/method signature from the body. If the signature is on one line, the separation is clear (image on the left), if it's on multiple lines, in PSR the signatures and bodies blend together (in the middle), while in the Nette standard they remain separated (on the right):

[* new-line-after.webp *]


Documentation Blocks (phpDoc)
=============================

The main rule: never duplicate any signature information like parameter type or return type with no added value.

Documentation block for class definition:

- Starts by a class description.
- Empty line follows.
- The `@property` (or `@property-read`, `@property-write`) annotations follow, one by line. Syntax is: annotation, space, type, space, $name.
- The `@method` annotations follow, one by line. Syntax is: annotation, space, return type, space, name(type $param, ...).
- The `@author` annotation is omitted. The authorship is kept in a source code history.
- The `@internal` or `@deprecated` annotations can be used.

```php
/**
 * MIME message part.
 *
 * @property string $encoding
 * @property-read array $headers
 * @method string getSomething(string $name)
 * @method static bool isEnabled()
 */
```

Documentation block for property that contains only `@var` annotation should be in single line:

```php
/** @var string[] */
private array $name;
```

Documentation block for method definition:

- Starts by a short method description.
- No empty line.
- The `@param` annotations, one by line.
- The `@return` annotation.
- The `@throws` annotations, one by line.
- The `@internal` or `@deprecated` annotations can be used.

Every annotation is followed by one space, except for the `@param` which is followed by two spaces for better readability.

```php
/**
 * Finds a file in directory.
 * @param  string[]  $options
 * @return string[]
 * @throws DirectoryNotFoundException
 */
public function find(string $dir, array $options): array
```


Tabs Instead of Spaces
======================

Tabs have several advantages over spaces:

- indent size is customisable in editors & "web":https://developer.mozilla.org/en-US/docs/Web/CSS/tab-size
- they do not impose the user's indentation size preference on the code, so the code is more portable
- you can type them with one keystroke (anywhere, not just in editors that turn tabs into spaces)
- indentation is their purpose
- respect the needs of visually impaired and blind colleagues

By using tabs in our projects, we allow for width customization, which may seem unnecessary to most people, but is essential for people with visual impairments.

For blind programmers who use braille displays, each space is represented by a braille cell and takes up valuable space. So if the default indentation is 4 spaces, a 3rd level indentation wastes 12 braille cells before the code begins.
On a 40-cell display, which is the most commonly used on laptops, that's more than a quarter of the available cells wasted without any information.


{{priority: -1}}

Coding Standard

This document describes rules and recommendations for developing Nette. When contributing code to Nette, you must follow them. The easiest way how to do it is to imitate the existing code. The idea is to make all the code look like it was written by one person.

Nette Coding Standard corresponds to PSR-12 Extended Coding Style with two main exceptions: it uses tabs instead of spaces for indentation, and uses PascalCase for class constants.

General Rules

  • Every PHP file must contain declare(strict_types=1)
  • Two empty lines are used to separate methods for better readability.
  • The reason for using shut-up operator must be documented: @mkdir($dir); // @ - directory may exist
  • If weak typed comparison operator is used (ie. ==, !=, …), the intention must be documented: // == to accept null
  • You can write more exceptions into one file exceptions.php
  • The visibility of methods is not specified for interfaces because they are always public.
  • Each property, return value, and parameter must have a type specified. On the other hand, for final constants, we never specify the type because it is obvious.
  • Single quotes should be used to delimit the string, except when the literal itself contains apostrophes.

Naming Conventions

Wrapping and Braces

Nette Coding Standard corresponds to PSR-12 (or PER Coding Style), in some points it specifies it more or modifies it:

  • arrow functions are written without a space before the parenthesis, i.e. fn($a) => $b
  • no empty line is required between different types of use import statements
  • the return type of a function/method and the opening curly bracket are always on separate lines:
	public function find(
		string $dir,
		array $options,
	): array
	{
		// method body
	}

The opening curly bracket on a separate line is important for visually separating the function/method signature from the body. If the signature is on one line, the separation is clear (image on the left), if it's on multiple lines, in PSR the signatures and bodies blend together (in the middle), while in the Nette standard they remain separated (on the right):

Documentation Blocks (phpDoc)

The main rule: never duplicate any signature information like parameter type or return type with no added value.

Documentation block for class definition:

  • Starts by a class description.
  • Empty line follows.
  • The @property (or @property-read, @property-write) annotations follow, one by line. Syntax is: annotation, space, type, space, $name.
  • The @method annotations follow, one by line. Syntax is: annotation, space, return type, space, name(type $param, …).
  • The @author annotation is omitted. The authorship is kept in a source code history.
  • The @internal or @deprecated annotations can be used.
/**
 * MIME message part.
 *
 * @property string $encoding
 * @property-read array $headers
 * @method string getSomething(string $name)
 * @method static bool isEnabled()
 */

Documentation block for property that contains only @var annotation should be in single line:

/** @var string[] */
private array $name;

Documentation block for method definition:

  • Starts by a short method description.
  • No empty line.
  • The @param annotations, one by line.
  • The @return annotation.
  • The @throws annotations, one by line.
  • The @internal or @deprecated annotations can be used.

Every annotation is followed by one space, except for the @param which is followed by two spaces for better readability.

/**
 * Finds a file in directory.
 * @param  string[]  $options
 * @return string[]
 * @throws DirectoryNotFoundException
 */
public function find(string $dir, array $options): array

Tabs Instead of Spaces

Tabs have several advantages over spaces:

  • indent size is customisable in editors & web
  • they do not impose the user's indentation size preference on the code, so the code is more portable
  • you can type them with one keystroke (anywhere, not just in editors that turn tabs into spaces)
  • indentation is their purpose
  • respect the needs of visually impaired and blind colleagues

By using tabs in our projects, we allow for width customization, which may seem unnecessary to most people, but is essential for people with visual impairments.

For blind programmers who use braille displays, each space is represented by a braille cell and takes up valuable space. So if the default indentation is 4 spaces, a 3rd level indentation wastes 12 braille cells before the code begins. On a 40-cell display, which is the most commonly used on laptops, that's more than a quarter of the available cells wasted without any information.