Migrating to Version 2.3

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

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


  • routes and presenter names are case sensitive. Nette will warn you if you use the wrong case in presenter name. But due to performance limitation it is not checking Route mask – you should check them manually. Correct is <presenter=UpperCasedDefaultValue> and <presenter url-cased-regexp-mask>.
  • Route::addStyle() & Route::setStyleProperty() are deprecated and now will trigger E_USER_DEPRECATED
  • unsupported template extension .phtml and old link syntax


  • removed deprecated constants Configurator::DEVELOPMENT and PRODUCTION
  • Configurator::setDebugMode() accepts only bool / string / array
  • in config file you can move all sections placed in nette to one level up. If you move up one of the sections container, mailer or debugger, rename it to di, mail and tracy.


  • ancient and deprecated ArrayAccess syntax $val = $cache[$key] or $cache[$key] = $val triggers E_USER_DEPRECATED. Use please $cache->load($key) and $cache->save($key, $val)


  • MySqlDriver by default uses utf8mb4 encoding for MySQL >= 5.5.3 instead of utf8 (see, maybe it will be reverted)
  • IReflection was changed to twins IStructure and IConventions
  • to ensure that new SQL translator do the same job as older one, you can install special tool named CompatibilityChecker22


  • removed support for placing services inside extension section in configuration file
  • removed support for dynamically added extensions
  • for replacing service dynamically (through removeService, addService calls), newly added service must be instance of same interface/class as original service


  • Finder::filter() callback always receives as argument (at least) a FilesystemIterator


  • internal filtering methods like Nette\Forms\Controls\TextBase::filterFloat was removed
  • internal validation methods like Nette\Forms\Controls\TextBase::validateFloat was moved to Nette\Forms\Validator, as well as Rules::$defaultMessages
  • Buttons and Hidden fields are generated without HTML ID. Relying on autogenerated ID is very bad, if you want ID, set it via setHtmlId()
  • RadioList items are generated without ID too. You can enable it via $radioList->generateId = true. But again: set you base ID via setHtmlId()
  • filters added via TextBase::addFilter() are processed during validation.
  • now you can add filters to conditions $input->addCondition(...)->addFilter(...)


  • Request::getUrl() is immutable


  • if you use variable $mail in template, you have to pass it to the template manually
  • but better than {var $mail->subject = "Your new order"} is this <title>Your new order</title>, isn't it?
  • if you have linked images (with relative paths) in template, pass base file path to images as second parameter to setHtmlBody()
  • there is no need to cast templates to (string)


  • is now case sensitive and will warn you if you use the wrong case in class name


  • it is recommended to change protocol safe://... to namespaced nette.safe://...


  • fasten your belt if you will use Tracy, she is now really fast :-)


  • Image::from() throws ImageException when is unable to decode file
  • Image::getFormatFromString is deprecated
  • Strings::chr and normalize now works only with UTF-8 encoding
  • Strings::chr() throws Nette\InvalidArgumentException if code point is not in valid range