Nette Documentation Preview

syntax
Migrating to Version 2.1
************************

.[perex]
There are [#new features] and some [incompatibilities|#Backward Incompatible Changes] that should be considered, and code should be tested before switching to new Nette Framework version.


New Features
============


Application & Presenter
-----------------------
- Presenter: new method `sendJson()`
- PresenterFactory: configurable mapping Presenter name -> Class name
- Route: new pseudo-variables `%basePath%`, `%tld%` and `%domain%`


Caching
-------
- added SQLite storage (`Nette/Caching/Storages/SQLiteStorage`)


Database (NDB)
--------------
- complete refactoring, a ton of bug fixes
- Connection:
	- lazy connection
	- all queries are logged (error queries, transactions, …)
	- added onConnect event
	- DSN in connection panel
- much better (dibi-like) SQL preprocessor
- Selection, ActiveRow: insert() & update() methods return row instances with refetched data
- Selection: added placeholder support select(), group(), having(), order() methods
- SqlLiteral: added placeholder support
- Selection:
	- added: WHERE conditions consider NOT for IN operator
	- insert() method returns IRow
- drivers:
	- new driver for Sqlsrv
	- Sqlite supports multi-inserts
	- fixes for PostgreSQL


Debugger
--------
- Dumper: colored and clickable dumps in HTML or terminal
- Debugger: full stack trace on fatal errors (requires Xdebug)
- Debugger: method `barDump()` accepts options
- BlueScreen: new property `$collapsePaths` which allows you to configure which paths are collapses in stack trace
- Bar: you can see bar after redirect
- Bar: new method `getPanel()`
- Dumper: possibility to include JS & CSS separately


Dependency Injection (DI)
-------------------------
- annotation @inject
- auto-generated factories and accessors via interface
- adding compiler extensions via config file
- auto-detection of sections in config file
- configurable presenters via config file
- Container: new methods `findByType()` and `callInjects()`


Forms
-----
- new macro `n:name` for `<form> <input> <select> <textarea>`
- partially rendered radiolists using `{input name:$key}` and `{label name:$key}`
- setOmitted: excludes value from $form->getValues() result
- removed dependency on Environment
- improved toggles
- improved netteForms.js
- validation scopes
- data-nette-rules attribute is JSON
- `getOwnErrors()` returns only errors attached to form
- Radiolist::getLabel(..., $key) returns label for single item


HTTP
----
- added new SessionPanel
- Helpers: new method `ipMatch()`
- RequestFactory: new method `setProxy()`
- Url: new methods `getQueryParameter()` and `setQueryParameter()`


Latte
-----
- new modifier `|noescape` which is preferred over exclamation mark
- new macro `n:ifcontent`
- `{include block}` can be written without hash
- template allows helpers overriding
- native support for empty macros `{macro /}`
- a lot of small improvements
- PhpWriter supports indexed arguments like %1.raw


Utils
-----
- Arrays: new method `isList()`
- Arrays: method `flatten()` supports key preserving
- Strings: new methods `findPrefix()` and `normalizeNewLines()`
- Json: supports pretty output
- Neon: is superset of JSON
- Validators: new method `isType()`
- new utility class `FileSystem`
- new utility class `Callback`


Mailing
-------
- SmtpMailer: persistent connection
- SmtpMailer: some methods protected and can be overloaded


Others
------
- ObjectMixin: new methods `getMagicMethods`, `getExtensionMethod`, `setExtensionMethod` and `checkType`
- ObjectMixin: magic methods setProperty(), getProperty(), isProperty() and addProperty() by @method
- both `RobotLoader` and `NetteLoader` can be registered before existing autoloaders instead of after
- SafeStream: supports `ftruncate` (requires PHP 5.4+)


Backward Incompatible Changes
=============================


Database (NDB)
--------------

- `Nette\Database\Connection` is not a descendant of `PDO`:https://www.php.net/manual/en/class.pdo.php
- rename methods `exec()` -> `query()`, `fetchColumn()` -> `fetchField()` and `lastInsertId()` -> `getInsertId()`
- `Nette\Database\Statement` rename to `Nette\Database\ResultSet`, which is not a descendant of `PDOStatement`:https://www.php.net/manual/en/class.pdostatement.php
- rename methods `rowCount()` -> `getRowCount()` and `columnCount()` -> `getColumnCount()`
- MySQL: removed timezone setting. Use onConnect[] event instead. ("commit":https://github.com/nette/nette/commit/61c9d9f1c254334e82b9388cdc95d3256e6fd71e)

Are you using Nette Database Table (NDBT), a great part of the NDB to which is accessed via `$database->table(...)`?

- method `table()` was moved from `Connection` to new class `Nette\Database\Context`. It contains all of the important methods for working with databases, so feel free to change the `Connection` for `Context` and you're done.
- properties of `ActiveRow` are now read-only, for updating use `$row->update(['field' => 'value'])`. The old behavior had so many difficulties, sorry.
- backjoin syntax was changed from `book_tag:tag.name` to `:book_tag.tag.name` (see semicolons)
- instead of second argument `$having` in method `group()` use method `having()`
- Selection: removed support for INNER join in where statement ("commit":https://github.com/nette/nette/commit/68314840e2429351d1e37e00c6070a21bdc36744)


Dependency Injection (DI)
-------------------------

- class `Nette\Config\Configurator` -> `Nette\Configurator`
- definitions of factories and services in configuration file were merged into a single `services` section. Append key `autowired: false` to the factories when moving them to `services` section.
- introduced "bullet" syntax for anonymous services:

```neon
services:
	Namespace\Class: self  # old way

	- Namespace\Class  # new way
```

Working directly with the DI container is usually not a good idea, but if you do so:
- factory method call as `$container->createService('name')` instead of `$container->createName()`
- all default factories are deprecated: `createLatte()`, `createCache()`, `createMail()` a `createBasicForm()`
- access to services via `$container->getService()` or `getByType()` instead of `$container->serviceName`
- Container: removed property `$classes`, removed parameter `$meta` in method `addService()`
- ServiceDefinition: removed property `$internal` and method `setInternal()`
- ContainerBuilder: method `generateClass()` is deprecated, use `generateClasses()[0]` instead
- ContainerBuilder operates on expanded parameters, removed `Helpers: escape()`
- Configurator: deprecated parameter `productionMode`, use `debugMode` instead
- Configurator: methods `setProductionMode`, `isProductionMode` and `detectProductionMode` are deprecated, use `*Debug*` variants instead
- Container: removed deprecated property `$params`, use `$parameters` instead

If you write your own extensions, you should know that these namespaces was renamed: `Nette\Config` -> `Nette\DI` and `Nette\Utils\PhpGenerator` -> `Nette\PhpGenerator`.

Compared to the dev-version the annotation `@inject` a methods `inject()` are processed automatically only for presenters. They can be enabled using key `inject: true` in the definition.

If you are using old `Environment`, it will require to set constant `TEMP_DIR`.


Application & Presenter
-----------------------
- Presenter doesn't accept array in persistent parameters anymore. If you really do want to use arrays, assign empty array as default value.
- deprecated all of the following methods: `getService()` (use `getContext()->getService()`), `getHttpContext()` and `getApplication()`
- magical `getParameter(null)` -> `getParameters()`
- you can use `redrawControl()` instead of `invalidateControl()`
- Application: methods `storeRequest()` and `restoreRequest()` are deprecated, call them on `UI\Presenter` instead
- Application\Routers\Route: foo-parameters are not optional when pattern is missing


Latte
-----
- default mode is HTML (instead of XHTML); if you need to use XHTML, please see configuration
- automatic quoting of attributes in `<a title={$title}>`; this should not cause any trouble, but it's better to mention it just in case
- renamed `n:input` to `n:name`; it can be used on tags other than `<input>`, like label, select, form and textarea
- deprecated `{attr}` (replaced by `n:attr`) and `{assign}` -> `{var}`
- it's now best practice to use `{$var|noescape}` instead of old "exclamation mark" notation `{!$var}`, it's more clearer
- shorter macro for blocks `{#block}` (present in development version) was not included in version 2.1 due to comprehension reasons
- native support for empty macros, use for example `{label foo /}` instead of `{label foo}`

Latte contains a new feature which automatically checks if variable `$url` in `<a href={$url}>` contains malicious code (like `javascript:siteHack()`). It only allows http, https, ftp, mailto protocols and relative paths. It also checks in attributes src, action, formaction and `<object data=...>`. Should you need to print URL without checking, use `|nosafeurl` modifier.

There also was a small change with manual rendering of checkboxes, which is described later in the article.


Forms
-----
Checkboxes and RadioLists are now rendered in more practical way (`<label><input>...</label>` instead of `<label>...</label><input>`). Therefore, Checkbox's method `getLabel()` or `{label}` return nothing and `getControl()` or `{input}` return HTML in the new form. Should you need previous behavior, you can achieve it by so-called partial rendering by adding colon (`{label elementName:}` and `{input elementName:}`). Easy.

Macro `{control form}` always prints error messages next to controls; only unassigned errors are shown in the beginning of the form. It is recommended to do it like this when rendering form manually, "as can be seen in the example":https://github.com/nette/sandbox/blob/f1819483da6467af1706fbc6b5679aa2f79aa8d0/app/templates/components/form.latte.

- `setValue()` checks value and throws exception if something is wrong (instead of ignoring any errors)
- validation rules `Form::INTEGER`, `NUMERIC` and `FLOAT` cast the value to integer or float
- TextArea: removed default values of attributes `cols` and `rows` (they were included only because HTML4 required them)
- controls marked `setDisabled()` are not present in `$form->getValues()` (they are not sent by the browser)
- deprecated `SelectBox::setPrompt(true)`; use string instead of true
- renamed `MultiSelectBox::getSelectedItem()` -> `getSelectedItems()`
- HTML attributes as `data-nette-rules` contains JSON, don't forget to update `netteForms.js` to latest version
- Form: removed deprecated event `$onInvalidSubmit`, use `$onError` instead
- RadioList: calling `getValue(true)` is deprecated, use `getRawValue()` instead


Debugger
--------
- `Nette\Diagnostics\Debugger::$blueScreen` -> `Debugger::getBlueScreen()`
- and similarly `$bar` -> `getBar()`, `$logger` -> `getLogger()` a `$fireLogger` -> `getFireLogger()`
- deprecated `Nette\Diagnostics\Debugger::tryError()`, `catchError()` and also `toStringException()`, use standard `trigger_error()` instead
- deprecated internal `Nette\Diagnostics\Helpers::clickableDump()` and `htmlDump()`, which were replaced by `Dumper`


Mail
----
- Deprecated method `Nette\Mail\Message::send()`, use mailer
- Mail\Message: methods `setHtmlBody()` and `setBody()` render template immediately
- MimePart: removed method `generateMessage()`, use `getEncodedMessage()` instead


Miscellaneous
-------------
- Nette Framework dropped support for PHP 5.2; to ease migration to namespaces, `migration-53.php` utility is available
- minimized version is generated in "PHAR format":https://www.php.net/manual/en/book.phar.php, therefore there's `nette.phar` instead of `nette.min.php` in the distribution. Usage is the same.
- `Nette\Utils\Finder::find($mask)` filters both directories and files by mask
- `Nette\Security\User` accepts authenticator in constructor, beware of circular dependencies
- loader doesn't set `iconv_set_encoding()` and `mb_internal_encoding()` anymore
- deprecated constants `NETTE, NETTE_DIR and NETTE_VERSION_ID`
- deprecated class `Nette\Loaders\AutoLoader`
- deprecated variable `Nette\Framework::$iAmUsingBadHost`
- we recommend you to stop using `callback()` and class `Nette\Callback`, because global functions can cause "troubles":https://github.com/nette/nette/issues/1187
- renamed namespace `Nette\Utils\PhpGenerator` -> `Nette\PhpGenerator`
- Nette shows warning „Possible problem: you are sending a cookie while already having some data in output buffer,“ if you are trying to send HTTP headers or cookies and previous output was sent to buffer. The error is shown because buffer may overflow.
- InstanceFilter: removed entirely
- RecursiveFilter: removed method `accept()` and parameter `$childrenCallback` in constructor
- RequestFactory: removed method `setEncoding()`, only UTF-8 and binary (via `setBinary()`) is now supported
- ObjectMixin: removed method `callProperty()`
- ObjectMixin: removes support for non-registered extension methods (`*_prototype_*` functions)

{{priority: -5}}

Migrating to Version 2.1

There are new features and some incompatibilities that should be considered, and code should be tested before switching to new Nette Framework version.

New Features

Application & Presenter

  • Presenter: new method sendJson()
  • PresenterFactory: configurable mapping Presenter name → Class name
  • Route: new pseudo-variables %basePath%, %tld% and %domain%

Caching

  • added SQLite storage (Nette/Caching/Storages/SQLiteStorage)

Database (NDB)

  • complete refactoring, a ton of bug fixes
  • Connection:
    • lazy connection
    • all queries are logged (error queries, transactions, …)
    • added onConnect event
    • DSN in connection panel
  • much better (dibi-like) SQL preprocessor
  • Selection, ActiveRow: insert() & update() methods return row instances with refetched data
  • Selection: added placeholder support select(), group(), having(), order() methods
  • SqlLiteral: added placeholder support
  • Selection:
    • added: WHERE conditions consider NOT for IN operator
    • insert() method returns IRow
  • drivers:
    • new driver for Sqlsrv
    • Sqlite supports multi-inserts
    • fixes for PostgreSQL

Debugger

  • Dumper: colored and clickable dumps in HTML or terminal
  • Debugger: full stack trace on fatal errors (requires Xdebug)
  • Debugger: method barDump() accepts options
  • BlueScreen: new property $collapsePaths which allows you to configure which paths are collapses in stack trace
  • Bar: you can see bar after redirect
  • Bar: new method getPanel()
  • Dumper: possibility to include JS & CSS separately

Dependency Injection (DI)

  • annotation @inject
  • auto-generated factories and accessors via interface
  • adding compiler extensions via config file
  • auto-detection of sections in config file
  • configurable presenters via config file
  • Container: new methods findByType() and callInjects()

Forms

  • new macro n:name for <form> <input> <select> <textarea>
  • partially rendered radiolists using {input name:$key} and {label name:$key}
  • setOmitted: excludes value from $form->getValues() result
  • removed dependency on Environment
  • improved toggles
  • improved netteForms.js
  • validation scopes
  • data-nette-rules attribute is JSON
  • getOwnErrors() returns only errors attached to form
  • Radiolist::getLabel(…, $key) returns label for single item

HTTP

  • added new SessionPanel
  • Helpers: new method ipMatch()
  • RequestFactory: new method setProxy()
  • Url: new methods getQueryParameter() and setQueryParameter()

Latte

  • new modifier |noescape which is preferred over exclamation mark
  • new macro n:ifcontent
  • {include block} can be written without hash
  • template allows helpers overriding
  • native support for empty macros {macro /}
  • a lot of small improvements
  • PhpWriter supports indexed arguments like %1.raw

Utils

  • Arrays: new method isList()
  • Arrays: method flatten() supports key preserving
  • Strings: new methods findPrefix() and normalizeNewLines()
  • Json: supports pretty output
  • Neon: is superset of JSON
  • Validators: new method isType()
  • new utility class FileSystem
  • new utility class Callback

Mailing

  • SmtpMailer: persistent connection
  • SmtpMailer: some methods protected and can be overloaded

Others

  • ObjectMixin: new methods getMagicMethods, getExtensionMethod, setExtensionMethod and checkType
  • ObjectMixin: magic methods setProperty(), getProperty(), isProperty() and addProperty() by @method
  • both RobotLoader and NetteLoader can be registered before existing autoloaders instead of after
  • SafeStream: supports ftruncate (requires PHP 5.4+)

Backward Incompatible Changes

Database (NDB)

  • Nette\Database\Connection is not a descendant of PDO
  • rename methods exec()query(), fetchColumn()fetchField() and lastInsertId() → getInsertId()
  • Nette\Database\Statement rename to Nette\Database\ResultSet, which is not a descendant of PDOStatement
  • rename methods rowCount()getRowCount() and columnCount() → getColumnCount()
  • MySQL: removed timezone setting. Use onConnect[] event instead. (commit)

Are you using Nette Database Table (NDBT), a great part of the NDB to which is accessed via $database->table(...)?

  • method table() was moved from Connection to new class Nette\Database\Context. It contains all of the important methods for working with databases, so feel free to change the Connection for Context and you're done.
  • properties of ActiveRow are now read-only, for updating use $row->update(['field' => 'value']). The old behavior had so many difficulties, sorry.
  • backjoin syntax was changed from book_tag:tag.name to :book_tag.tag.name (see semicolons)
  • instead of second argument $having in method group() use method having()
  • Selection: removed support for INNER join in where statement (commit)

Dependency Injection (DI)

  • class Nette\Config\ConfiguratorNette\Configurator
  • definitions of factories and services in configuration file were merged into a single services section. Append key autowired: false to the factories when moving them to services section.
  • introduced „bullet“ syntax for anonymous services:
services:
	Namespace\Class: self  # old way

	- Namespace\Class  # new way

Working directly with the DI container is usually not a good idea, but if you do so:

  • factory method call as $container->createService('name') instead of $container->createName()
  • all default factories are deprecated: createLatte(), createCache(), createMail()createBasicForm()
  • access to services via $container->getService() or getByType() instead of $container->serviceName
  • Container: removed property $classes, removed parameter $meta in method addService()
  • ServiceDefinition: removed property $internal and method setInternal()
  • ContainerBuilder: method generateClass() is deprecated, use generateClasses()[0] instead
  • ContainerBuilder operates on expanded parameters, removed Helpers: escape()
  • Configurator: deprecated parameter productionMode, use debugMode instead
  • Configurator: methods setProductionMode, isProductionMode and detectProductionMode are deprecated, use *Debug* variants instead
  • Container: removed deprecated property $params, use $parameters instead

If you write your own extensions, you should know that these namespaces was renamed: Nette\ConfigNette\DI and Nette\Utils\PhpGeneratorNette\PhpGenerator.

Compared to the dev-version the annotation @inject a methods inject() are processed automatically only for presenters. They can be enabled using key inject: true in the definition.

If you are using old Environment, it will require to set constant TEMP_DIR.

Application & Presenter

  • Presenter doesn't accept array in persistent parameters anymore. If you really do want to use arrays, assign empty array as default value.
  • deprecated all of the following methods: getService() (use getContext()->getService()), getHttpContext() and getApplication()
  • magical getParameter(null)getParameters()
  • you can use redrawControl() instead of invalidateControl()
  • Application: methods storeRequest() and restoreRequest() are deprecated, call them on UI\Presenter instead
  • Application\Routers\Route: foo-parameters are not optional when pattern is missing

Latte

  • default mode is HTML (instead of XHTML); if you need to use XHTML, please see configuration
  • automatic quoting of attributes in <a title={$title}>; this should not cause any trouble, but it's better to mention it just in case
  • renamed n:input to n:name; it can be used on tags other than <input>, like label, select, form and textarea
  • deprecated {attr} (replaced by n:attr) and {assign} → {var}
  • it's now best practice to use {$var|noescape} instead of old „exclamation mark“ notation {!$var}, it's more clearer
  • shorter macro for blocks {#block} (present in development version) was not included in version 2.1 due to comprehension reasons
  • native support for empty macros, use for example {label foo /} instead of {label foo}

Latte contains a new feature which automatically checks if variable $url in <a href={$url}> contains malicious code (like javascript:siteHack()). It only allows http, https, ftp, mailto protocols and relative paths. It also checks in attributes src, action, formaction and <object data=...>. Should you need to print URL without checking, use |nosafeurl modifier.

There also was a small change with manual rendering of checkboxes, which is described later in the article.

Forms

Checkboxes and RadioLists are now rendered in more practical way (<label><input>...</label> instead of <label>...</label><input>). Therefore, Checkbox's method getLabel() or {label} return nothing and getControl() or {input} return HTML in the new form. Should you need previous behavior, you can achieve it by so-called partial rendering by adding colon ({label elementName:} and {input elementName:}). Easy.

Macro {control form} always prints error messages next to controls; only unassigned errors are shown in the beginning of the form. It is recommended to do it like this when rendering form manually, as can be seen in the example.

  • setValue() checks value and throws exception if something is wrong (instead of ignoring any errors)
  • validation rules Form::INTEGER, NUMERIC and FLOAT cast the value to integer or float
  • TextArea: removed default values of attributes cols and rows (they were included only because HTML4 required them)
  • controls marked setDisabled() are not present in $form->getValues() (they are not sent by the browser)
  • deprecated SelectBox::setPrompt(true); use string instead of true
  • renamed MultiSelectBox::getSelectedItem()getSelectedItems()
  • HTML attributes as data-nette-rules contains JSON, don't forget to update netteForms.js to latest version
  • Form: removed deprecated event $onInvalidSubmit, use $onError instead
  • RadioList: calling getValue(true) is deprecated, use getRawValue() instead

Debugger

  • Nette\Diagnostics\Debugger::$blueScreenDebugger::getBlueScreen()
  • and similarly $bargetBar(), $loggergetLogger() a $fireLogger → getFireLogger()
  • deprecated Nette\Diagnostics\Debugger::tryError(), catchError() and also toStringException(), use standard trigger_error() instead
  • deprecated internal Nette\Diagnostics\Helpers::clickableDump() and htmlDump(), which were replaced by Dumper

Mail

  • Deprecated method Nette\Mail\Message::send(), use mailer
  • Mail\Message: methods setHtmlBody() and setBody() render template immediately
  • MimePart: removed method generateMessage(), use getEncodedMessage() instead

Miscellaneous

  • Nette Framework dropped support for PHP 5.2; to ease migration to namespaces, migration-53.php utility is available
  • minimized version is generated in PHAR format, therefore there's nette.phar instead of nette.min.php in the distribution. Usage is the same.
  • Nette\Utils\Finder::find($mask) filters both directories and files by mask
  • Nette\Security\User accepts authenticator in constructor, beware of circular dependencies
  • loader doesn't set iconv_set_encoding() and mb_internal_encoding() anymore
  • deprecated constants NETTE, NETTE_DIR and NETTE_VERSION_ID
  • deprecated class Nette\Loaders\AutoLoader
  • deprecated variable Nette\Framework::$iAmUsingBadHost
  • we recommend you to stop using callback() and class Nette\Callback, because global functions can cause troubles
  • renamed namespace Nette\Utils\PhpGeneratorNette\PhpGenerator
  • Nette shows warning „Possible problem: you are sending a cookie while already having some data in output buffer,“ if you are trying to send HTTP headers or cookies and previous output was sent to buffer. The error is shown because buffer may overflow.
  • InstanceFilter: removed entirely
  • RecursiveFilter: removed method accept() and parameter $childrenCallback in constructor
  • RequestFactory: removed method setEncoding(), only UTF-8 and binary (via setBinary()) is now supported
  • ObjectMixin: removed method callProperty()
  • ObjectMixin: removes support for non-registered extension methods (*_prototype_* functions)