Migrating to Version 2.4

Minimum required PHP version is 5.6 (for Latte and Tracy 5.4).

Nette version 2.4 means that you have these packages installed in version 2.4.*:

"require": {
	"nette/application": "2.4.*",
	"nette/bootstrap": "2.4.*",
	"nette/di": "2.4.*",
	"nette/forms": "2.4.*",
	"nette/http": "2.4.*",
	"nette/security": "2.4.*",

Warning: for other packages, install the latest version that Composer will allow! They may have different versioning. Try "*" and see what version Composer installs.

Deprecated Stuff

Before testing we recommend to disable reporting E_USER_DEPRECATED and allow it when everything will work:

error_reporting(~E_USER_DEPRECATED); // note ~ before E_USER_DEPRECATED


Framework classes now use trait Nette\SmartObject instead of inheriting from Nette\Object, which differs in several cases:

  • supports “emulated properties” only when exists annotation @property type $name
  • doesn't support “extension methods”
  • doesn't support “getReflection”
  • doesn't support getting methods such as $this->formSubmitted (it is necessary to replace a classic PHP callback [$this, 'formSubmitted']

Using of these features generates E_USER_DEPRECATED and they will be removed in the next version.


Latte generates deprecation notices if:

  • construction {foreach $langs as $lang} overwrites template parameter $lang
  • using obsolete convention {!$name} instead of {$name|noescape}
  • using <?php ?> or {? ...} instead of {php ...}
  • using filter for block or include that is for another content type
  • using |nosafeurl instead of |nocheck
  • using {includeblock}, which replaces the similar macro {import} (just imports blocks, not content around)
  • error “Incompatible context” occurs when using the block in another context (for example, inside an HTML attribute without quotes), than was defined (for example in normal HTML text)
  • accessing variable $template for filters; use ($var|trim)
  • accessing variable $template for parameters; use $this->getParameter('xyz')
  • accessing to internal underscored variables as $_control, $_form etc.

Bootstrap and DI

Deprecated are:

  • sections (ie. production, development) in single configuration file; use a pair of configuration files config.neon and config.local.neon
  • service definitions inheritance
  • Statement::setEntity()


  • Negative validation rules. An alternative for the ~Form::FILLED is Form::BLANK, or ~Form::EQUAL can be replaced with Form::NOT_EQUAL
  • Nette\Utils\Html::add() is replaced with addHtml() and addText()
  • In PhpGenerator methods setDocuments(), getDocuments() and addDocument() was replaced by setComment(), getComment() and addComment()
  • Flag SECURED and Route::$defaultFlags are deprecated



Route and SimpleRouter now generate the same HTTP/HTTPS scheme as was used to access the site. Route, which require specific protocol, can be defined with scheme (Route('http://domain.cz/<presenter>').

For parameters of type bool used to render/action methods (ie. parameters with default value of true or false) and persistent parameters are now distinguishes between false and null. If the query parameter is not specified, its value is now null, previously it was false. See nette/application#107.

The class, which returns Presenter::getReflection() is not a descendant of Nette\Reflection\ClassType and also getReflection()->getMethod() is not a descendant of Nette\Reflection\Method. Methods hasAnnotation and getAnnotation do not parse text following annotation name, such as abc in @param abc, they parse text in parentheses @param(abc).


If the form item has a rule via addRule() (that means item is effectively mandatory), you must also set is as mandatory via setRequired(). Furthermore, setRequired(false) now sets item as optional. This replaces branches addCondition($form::FILLED).

Internal underscored variables such as $_form are deprecated. If you ever had to manually pass this variable into template because for snippets to work, this will now lead to an error (eg. end() expects parameter 1 to be array, null given). You can replace passing to template like $template->_form = $form with $template->getLatte()->addProvider('formsStack', [$form]), but it is still workaround, the correct solution is to use {snippetArea xyz} and the invalidate this area together with snippet.

Validators Form::EMAIL, URL and INTEGER automatically changes the HTML type attribute to email, url respectively number.

Internal parameter do is now sent via POST as _do to avoid a collision.

Class BaseControl defines getControlPart() and getLabelPart() and they return the same value as getControl() and getLabel(). Macros <tag n:name> directly use these methods.

DefaultFormRenderer now correctly added to the group nested components (formerly nested components was rendered at the end of the form), see nette/forms#96.

If you are using your own TemplateFactory, apply these changes done in the original factory.

Remember to update netteForms.js.


Filters used for text blocks ({block} or {_}...{/_}) or {include} must receive as the first parameter object Latte\Runtime\FilterInfo, see example.

Macro {contentType} is permitted only in the header of template, and in the element <script>.


Nette\Caching\Storages\FileJournal is no longer available.