You are browsing the unmaintained documentation for old Nette 2.0. See documentation for current Nette.

Configuring

System container is a DI container holding all the services and parameters needed for the application to run. Soon you will be able to:

  • create the system container
  • configure your application using NEON files
  • handle production and development modes
  • create and use your own container extensions

This page is still being prepared

System container is a static Dependency Injection container, that holds all services and parameters the application needs. This means not only services of the framework itself, but of each library you have decided to use. Take a look at an example of such system container.

Developers learned that writing containers is a very tedious work. And it surely gets difficult to manage the application as it grows. Nette will do the work for you! With a simple configuration language we will describe services of the application and the framework will generate the PHP code. In all seriousness – the container linked above was generated this way as well.

Configurator

The task of code generation is given to Nette\Config\Configurator class. The compilation process is triggered only once and its result is cached. For that reason we need to choose a directory for storing this code.

$configurator = new Nette\Config\Configurator;
$configurator->setTempDirectory(__DIR__ . '/../temp');

Now we just add a path to the config file:

$configurator->addConfig(__DIR__ . '/config/config.neon');

And getting container's instance is the simplest one:

// returns SystemContainer instance
$container = $configurator->createContainer();

Environment

Configurator attempts to detect if the application is running on production or development server. As long as the client's IP address is 127.0.0.1, server will be considered as developmental. We cannot find out which environment is used, but it doesn't care since it is used only for loading section from the configuration file. We can define it by a second parameter of addConfig().

$environment = Nette\Configurator::detectDebugMode('your ip address')
    ? $configurator::DEVELOPMENT
    : $configurator::PRODUCTION;

$configurator->addConfig(__DIR__ . '/config/config.neon', $environment);

We can pass any string by $environment, not only the production or development. By this, we can ask Configurator to load any section of configuration file. But a right detection is up to you (for example by system variable getenv('COMPUTERNAME') or server's hostname $_SERVER['SERVER_NAME']).

Development mode

A little bit different thing is an application running mode. We can access a production server as a developer and we want activate a Tracy debugger. The running mode is distinguished by the same principle as environment above, by client's IP address. We get the mode by isDebugMode() and set the mode by setDebugMode(). It is useful when we enable debugger by enableDebugger() which must be placed after the mode setting.

// activates Tracy debugger for listed IP adresses
$configurator->setDebugMode(array('90.180.45.360', '90.180.45.361'));
// or for anyone
$configurator->setDebugMode(); // = TRUE
// or for no one
$configurator->setDebugMode($configurator::NONE); // = FALSE

$configurator->enableDebugger(__DIR__ . '/../log');

Class Auto-loading

To compile the container, Configurator needs to load all the classes mentioned in a configuration files. It is handy to have auto-loading at your disposal and Configurator offers a method creating an instance of RobotLoader. We add only directories we wish to be indexed and activate the loader. Do not forget to place this code before calling createContainer().

$configurator->createRobotLoader()
    ->addDirectory(__DIR__)
    ->addDirectory(__DIR__ . '/../lib')
    ->register();

Framework configuration

Configuration is usually written in NEON format. Have fun trying out the syntax at http://ne-on.org. Many features of Nette Framework can be set up in configuration file. Framework configures itself by a DI container extension (Nette\DI\Extensions\NetteExtension)
which accepts parameters in nette: section of the configuration file.

Sessions

Here you can set all directives (in camelCase format).

nette:
    session:
        autoStart: true  # default is smart
        expiration: 10 days
        name: ...
        ...

autoStart: smart starts the session if it already exists and it is a recommended value

Application

nette:
    application:
        debugger: true  # debugger bar panel
        catchExceptions: %productionMode%
        errorPresenter: Front:Error

Routing

nette:
    routing:
        debugger: true  # debugger bar panel
        routes:
                index.php: Dashboard:default
                '<presenter>/<action>[/<id>]': Dashboard:default

Routes are in mask: action format.

Security

nette:
    security:
        debugger: true  # debugger bar panel
        frames: ...  # affects X-Frame-Options header

        users:
            johndoe: secretpassword

        roles:
            guest:
            member:
            admin: [member]  # admin extends member

        resources:
            file:

By filling in users option you create SimpleAuthenticator, by defining roles or resources you create Nette\Security\Permission authorizator. More in User Authorization and Privileges.

For security reasons Nette Framework sends HTTP header X-Frame-Options: SAMEORIGIN by default, so that the page can be embedded in iframe only from pages on the same domain. This behavior may be unwanted in certain situations (for example if you are developing a facebook application). You can override this setting by frames: yes, frames: http://allowed-host.com or frames: no.

Mailing

Default mailer is SendmailMailer. By setting smtp you activate SmtpMailer.

nette:
    mailer:
        smtp: true  # use SmtpMailer instead of SendmailMailer
        host: ...
        port: ...
        username: ...
        password: ...
        secure: ...
        timeout: ...

Database

You can define multiple database connections, if you do so you can set which one will be automatically injected to your services by the autowired option. The following code shows how to set up one connection called default.

nette:
    database:
        default:
            dsn: "sqlite2:%appDir%/models/demo.db"
            user: ...
            password: ...
            options: [PDO::MYSQL_ATTR_COMPRESS = true]
            debugger: false  # debugger bar panel
            explain: false  # explain queries in debugger bar
            reflection: discovered  # or conventional or classname, default is discovered
            autowired: true

This creates service @nette.database.default and sets reflection and cache for you.

Forms

You can change default validation error messages.

nette:
    forms:
        messages:
            EQUAL: 'Please enter %s.'
            FILLED: 'Please complete mandatory field.'
            MIN_LENGTH: 'Please enter a value of at least %d characters.'
            EMAIL: '%label must be valid e-mail'

Latte

You can turn on and off XHTML rendering mode and register custom macros.

nette:
    latte:
        xhtml: yes  # default is no
    macros:
        - App\MyLatteMacros::register  # static method, classname or callable

DI container

nette:
    container:
        debugger: true  #debugger bar panel

Debugger

nette:
    debugger:
        email: webmaster@example.com  # for sending error logs
        strictMode: TRUE
        editor: ...
        browser: ...

        bar:  # debugger bar panels
            - Nette\DI\Diagnostics\ContainerPanel  # alias of DI container bar
            - IncludePanel
            - XDebugHelper('myIdeKey')
            - MyPanel(@MyService)

        blueScreen:  # blue screen panels
            - DoctrinePanel::renderException

Low-level modifications

All these settings affect final DI container. Compared to direct definition in services section it provides shorter and more straightaway syntax. If you need to tune these services by yourself, you can redefine them:

services:
    nette.mailer:
        class: MySmtpMailer

    nette.presenterFactory:
        class: MyPresenterFactory

Or create new services extending the default ones:

services:
    myConnection < nette.database.default:
        setup:
            $onQuery: [ @logger::log ]

Custom services

Services definitions

services:
    database:
        class: Nette\Database\Connection(%dsn%, %user%, %password%)

#or in two lines
        class: Nette\Database\Connection
        arguments: [%dsn%, %user%, %password%]

Generates:

function createServiceDatabase()
{
    return new Nette\Database\Connection(
        $this->parameters['dsn'],
        $this->parameters['user'],
        $this->parameters['password']
    );
}

Service definition:

services:
    database:
        class: Nette\Database\Connection
        factory: DbFactory::createConnection

DbFactory::createConnection:

class DbFactory
{
    static function createConnection(Nette\DI\Container $container)
    {
        ...
    }
}

Generates:

function createServiceDatabase()
{
    return DbFactory::createConnection($this);
}

Setup

services:
    database:
        class: Nette\Database\Connection(%dsn%, %user%, %password%)
        setup:
            - setCacheStorage(@cacheStorage)

Generates:

function createServiceDatabase()
{
    $service = new Nette\Database\Connection(...);
    $service->setCacheStorage($this->cacheStorage);
    return $service;
}

Autowiring feature adds dependencies automatically, so they don't even have to be mentioned:

setup:
    - setCacheStorage

In case the cacheStorage service does not exist, it is possible to use a result of a call as a parameter:

setup:
    - setCacheStorage( Factory::createStorage() )

# or a method of other service:
    - setCacheStorage( @factory::createStorage() )

Alternatively a newly created class instance:

setup:
    - setCacheStorage( Nette\Caching\Storages\FileStorage(%tempDir%) )

# generates: $service->setCacheStorage(new Nette\Caching\Storages\FileStorage(...));

You can also set a value of a property:

substitutions

setup:
    - $substitutions( [db: test] )

# generates: $service->substitutions = array('db' => 'test');

Full example:

parameters:
    database:
        driver: mysql
        host: localhost
        dbname: test
        user: jim
        password: beam
        substitutions:
            db: test

services:
    database:
        class: Nette\Database\Connection(
            '%database.driver%:host=%database.host%;dbname=%database.dbname%',
            %database.user%, %database.password%, null,
            Nette\Database\Reflection\DiscoveredReflection()
        )
        setup:
            - setCacheStorage
            - $substitutions( %database.substitutions% )

Service definitions inheritance

services:
    dev_database < database
        setup:
            - Diagnostics\ConnectionPanel::initialize

Factories

Factories are defined in almost the same way as services:

factories:
    article:
        class: Article

Generates:

function createArticle()
{
    return new Article($this->database);
}

Factory is called directly like $article = $container->createArticle();

Unlike services a factory can accept parameters:

factories:
    article:
        parameters: [id, title: null]
        class: Article(..., %id%)
        setup:
            - $title(%title%)

Generates:

function createArticle($id, $title = NULL)
{
    $service = new Article($this->database, $id);
    $service->title = $title;
    return $service;
}

Auto-wiring

Auto-wiring feature can automatically pass dependencies into constructor and methods of the service. It uses typehinting and @return annotations. There can be only one service matching the type in the container, otherwise an exception is thrown.

To define more than one service of the same type we need to exclude them from auto-wiring:

services:
    cacheStorage:
        class: Nette\Caching\Storages\FileStorage(%tempDir%)

    tempCacheStorage:
        class: Nette\Caching\Storages\DevNullStorage
        autowired: no

When modifying the Nette Framework's core services we need to make sure the container is aware of the classes we want to use. That means using fully qualified class names in @return annotations or set the FQ class name with class entry.

Multiple configuration files

Use includes section to add more configuration files.

includes:
    - parameters.php
    - services.neon
    - presenters.neon

Configuration merging process assigns the highest priority to the file containing includes section and the lowest priority to the first included file. To prevent merging of a certain array use exclamation mark right after the name of the array:

argument!: [1, 2, 3]