Nette Documentation Preview

syntax
Presenters
**********

<div class=perex>

We will learn how to write presenters and templates in Nette. After reading you will know:

- how the presenters works
- what are persistent parameters
- how to render a template

</div>

[We already know |how-it-works#nette-application] that a presenter is a class that represents a specific page of a web application, such as a homepage; product in e-shop; sign-in form; sitemap feed, etc. The application can have from one to thousands of presenters. In other frameworks, they are also known as controllers.

Usually, the term presenter refers to a descendant of the class [api:Nette\Application\UI\Presenter], which is suitable for web interfaces and which we will discuss in the rest of this chapter. In a general sense, a presenter is any object that implements the [api:Nette\Application\IPresenter] interface.


Life Cycle of Presenter
=======================

The job of the presenter is to process the request and return a response (which can be an HTML page, image, redirect, etc.).

So at the beginning is a request. It is not directly an HTTP request, but an [api:Nette\Application\Request] object into which the HTTP request was transformed using a router. We usually do not come into contact with this object, because the presenter cleverly delegates the processing of the request to special methods, which we will now see.

[* lifecycle4.svg *] *** *Life cycle of presenter* .<>

The figure shows a list of methods that are called sequentially from top to bottom, if they exists. None of them need to exist, we can have a completely empty presenter without a single method and build a simple static web on it.


`__construct()`
---------------

The constructor does not belong exactly to the life cycle of the presenter, because it is called at the moment of creating the object. But we mention it because of its importance. The constructor (together with [method inject|best-practices:inject-method-attribute]) is used to pass dependencies.

The presenter should not take care of the business logic of the application, write and read from the database, perform calculations, etc. This is the task for classes from a layer, which we call a model. For example, class `ArticleRepository` may be responsible for loading and saving articles. In order for the presenter to use it, it is [passed using dependency injection |dependency-injection:passing-dependencies]:


```php
class ArticlePresenter extends Nette\Application\UI\Presenter
{
	/** @var ArticleRepository */
	private $articles;

	public function __construct(ArticleRepository $articles)
	{
		$this->articles = $articles;
	}
}
```


`startup()`
-----------

Immediately after receiving the request, method `startup ()` is invoked. You can use it to initialize properties, checks user privileges, etc. It is required to always call the `parent::startup()` ancestor.


`action<Action>(args...)` .{toc: action<Action>()}
--------------------------------------------------

Similar to the method `render<View>()`. While `render<View>()` is intended to prepare data for a specific template, which is subsequently rendered, in `action<Action>()` a request is processed without follow-up template rendering. For example, data is processed, a user is logged in or out, and so on, and then it [redirects elsewhere |#Redirection].

It is important that `action<Action>()` is called before `render<View>()`, so inside it we can possibly change the next course of life cycle, ie. change the template that will be rendered and also the method `render<View>()` that will be called, using `setView('otherView')`.

The parameters from the request are passed to the method. It is possible and recommended to specify types for the parameters by specifying their default value, eg `actionShow($id = 0, $slug = '')` - if parameter `id` is not an integer, the presenter returns [error 404|#Error 404 etc.] and terminates the operation.


`handle<Signal>(args...)` .{toc: handle<Signal>()}
--------------------------------------------------

This method processes the so-called signals, which we will discuss in the chapter about [Components |components#Signal]. It is intended mainly for components and processing of AJAX requests.

The parameters are passed to the method, as in the case of `action<Action>()`, including type checking.


`beforeRender()`
----------------

Method `beforeRender`, as the name suggests, is called before each method `render<View>()`. Is used for common template configuration, passing variables for layout and so on.


`render<View>(args...)` .{toc: render<View>()}
----------------------------------------------

The place where we prepare the template for subsequent rendering, we pass data to it, etc.

The parameters are passed to the method, as in the case of `action<Action>()`, including type checking.

```php
public function renderShow($id)
{
	// we obtain data from the model and pass it to the template
	$this->template->article = $this->articles->getById($id);
}
```


`afterRender()`
---------------

Method `afterRender`, as the name suggests again, is called after each `render<View>()` method. It is used rather rarely.


`shutdown()`
------------

It is called at the end of the presenter's life cycle.


**Good advice before we move on**. As you can see, the presenter can handle more actions/views, ie have more methods `render<View>()`. But we recommend designing presenters with one or as few actions as possible.


Sending a Response
==================

The presenter's response is usually [rendering the template with the HTML page|templates], but it can also be sending a file, JSON or even redirecting to another page.

At any time during the lifecycle, you can use any of the following methods to send a response and exit the presenter at the same time:

- `redirect()`, `redirectPermanent()`, `redirectUrl()` and `forward()` [redirects |#Redirection]
- `error()` quits presenter [due to error |#Error 404 etc.]
- `sendJson($data)` quits presenter and [sends the data |#Sending JSON] in JSON format
- `sendTemplate()` quits presenter and immediately [renderes the template |templates]
- `sendResponse($response)` quits presenter and sends [own response |#Responses]
- `terminate()` quits presenter without answer

If you do not call any of these methods, the presenter will automatically proceed to render the template. Why? Well, because in 99% of cases we want to draw a template, so the presenter takes this behavior as the default and wants to make our work easier.


Creating Links
==============

Presenter has a method `link()`, which is used to create URL links to other presenters. The first parameter is the target presenter & action, followed by the arguments, which can be passed as array:

```php
$url = $this->link('Product:show', $id);

$url = $this->link('Product:show', [$id, 'lang' => 'en']);
```

In template we create a links to other presenters & actions as follows:

```latte
<a n:href="Product:show $id">product detail</a>
```

Simply write the familiar `Presenter:action` pair instead of the real URL and include any parameters. The trick is `n:href`, which says that this attribute will be processed by Latte and generates a real URL. In Nette, you don't have to think about URLs at all, just about presenters and actions.

For more information, see [Creating Links].


Redirection
===========

Methods `redirect()` and `forward()` are used to jump to another presenter, which have a very similar syntax as the method [link() |#Creating Links].

The `forward()` switches to the new presenter immediately without HTTP redirection:

```php
$this->forward('Product:show');
```

Example of temporary redirection with HTTP code 302 or 303:

```php
$this->redirect('Product:show', $id);
```

To achieve permanent redirection with HTTP code 301 use:

```php
$this->redirectPermanent('Product:show', $id);
```

You can redirect to another URL outside the application with the `redirectUrl()` method:

```php
$this->redirectUrl('https://nette.org');
```

Redirection immediately terminates the presenter's life cycle by throwing the so-called silent termination exception `Nette\Application\AbortException`.

Before redirection, it is possible to send a [flash message |#Flash Messages], messages that will be displayed in the template after redirection.


Flash Messages
==============

These are messages that usually inform about the result of an operation. An important feature of flash messages is that they are available in the template even after redirection. Even after being displayed, they will remain alive for another three seconds - for example, in case the user would unintentionally refresh the page - the message will not be lost.

Just call the [flashMessage() |api:Nette\Application\UI\Control::flashMessage()] method and presenter will take care of passing the message to the template. The first argument is the text of the message and the second optional argument is its type (error, warning, info etc.). The method `flashMessage()` returns an instance of flash message, to allow us to add more information.

```php
$this->flashMessage('Item was removed.');
$this->redirect(/* ... */);
```

In the template, these messages are available in the variable `$flashes` as objects `stdClass`, which contain the properties `message` (message text), `type` (message type) and can contain the already mentioned user information. We draw them as follows:

```latte
{foreach $flashes as $flash}
	<div class="flash {$flash->type}">{$flash->message}</div>
{/foreach}
```


Error 404 etc.
==============

When we can't fulfill the request because for example the article we want to display does not exist in the database, we will throw out the 404 error using method `error(string $message = null, int $httpCode = 404)`, which represents HTTP error 404:

```php
public function renderShow($id)
{
	$article = $this->articles->getById($id);
	if (!$article) {
		$this->error();
	}
	// ...
}
```

The HTTP error code can be passed as the second parameter, the default is 404. The method works by throwing exception `Nette\Application\BadRequestException`, after which `Application` passes control to the error-presenter. Which is a presenter whose job is to display a page informing about the error.
The error-preseter is set in [application configuration |configuration].


Sending JSON
============

Example of action-method that sends data in JSON format and exits the presenter:

```php
public function actionData()
{
	$data = ['hello' => 'nette'];
	$this->sendJson($data);
}
```


Persistent Parameters
=====================

Persistent parameters are **transferred automatically** in links. This means that we do not have to explicitly specify them in every `link()` or `n:href` in the template, but they will still be transferred.

If your application has multiple language versions, then the current language is a parameter that must always be part of the URL. And it would be incredibly tiring to mention it in every link. That's not necessary with Nette. We simply mark the `lang` parameter as persistent in this way:

```php
class ProductPresenter extends Nette\Application\UI\Presenter
{
	/** @persistent */
	public $lang;
}
```

If the current value of the parameter `lang` is `'en'`, then the URL created with `link()` or `n:href` in the template will contain `lang=en`. Great!

However, we can also add parameter `lang` and by that change its value:

```latte
<a n:href="Product:show $id, lang => en">detail in English</a>
```

Or, conversely, it can be removed by setting to null:

```latte
<a n:href="Product:show $id, lang => null">click here</a>
```

The persistent variable must be declared as public. We can also specify a default value. If the parameter has the same value as the default, it will not be included in the URL.

Persistence reflects the hierarchy of presenter classes, thus parameter defined in a certain presenter is then automatically transferred to each presenter inheriting from it.


Interactive Components
======================

Presenters have a built-in component system. Components are separate reusable units that we place into presenters. They can be [forms|forms:in-presenter], datagrids, menus, in fact anything that makes sense to use repeatedly.

How are components placed and subsequently used in the presenter? This is explained in chapter [Components]. You'll even find out what they have to do with Hollywood.

Where Can I Get Some Components? On page [Componette |https://componette.org] you can find some open-source components and other addons for Nette that are made and shared by the community of Nette Framework.


Going Deeper
============

.[tip]
What we have shown so far in this chapter will probably suffice. The following lines are intended for those who are interested in presenters in depth and want to know everything.


Requirement and Parameters
--------------------------

The request handled by the presenter is the [api:Nette\Application\Request] object and is returned by the presenter's method `getRequest()`. It includes an array of parameters and each of them belongs either to some of the components or directly to the presenter (which is actually also a component, albeit a special one). So Nette redistributes the parameters
and passes between the individual components (and the presenter) by calling the method `loadState(array $params)`, which is further described in the chapter [Components]. The parameters can be obtained by the method `getParameters(): array`, individually using `getParameter($name)`. Parameter values ​​are strings or arrays of strings, they are basically raw data obtained directly from a URL.


Save and Restore the Request
----------------------------

You can save the current request to a session or restore it from the session and let the presenter execute it again. This is useful, for example, when a user fills out a form and it's login expires. In order not to lose data, before redirecting to the sign-in page, we save the current request to the session using `$reqId = $this->storeRequest()`, which returns an identifier in the form of a short string and passes it as a parameter to the sign-in presenter.

After sign in, we call the method `$this->restoreRequest($reqId)`, which picks up the request from the session and forwards it to it. The method verifies that the request was created by the same user as now logged in is. If another user logs in or the key is invalid, it does nothing and the program continues.


Canonization
------------

Presenters have one really great feature that improves SEO (optimization of searchability on the Internet). They automatically prevent the existence of duplicate content at different URLs. If multiple URLs lead to a certain destination, eg `/index` and `/index?page=1`, the framework designates one of them as the primary (canonical) and redirects the others to it using HTTP code 301. Thanks to this, search engines do not index pages twice and do not weaken their page rank.

This process is called canonization. The canonical URL is the URL generated by [router |routing], usually the first appropriate route in the collection.

Canonization is on by default and can be turned off via `$this->autoCanonicalize = false`.

Redirection does not occur with an AJAX or POST request because it would result in data loss or no SEO added value.

Since nette/application 2.4.6 you can also invoke canonization manually using method `canonicalize()`, which, like method `link()`, receives the presenter, actions, and parameters as arguments. It creates a link and compares it to the current URL. If it is different, it redirects to the generated link.

```php
public function actionShow($id, $slug = null)
{
	$realSlug = $this->facade->getSlugForId($id);
	// redirects if $slug is different from $realSlug
	$this->canonicalize('Product:show', [$id, $realSlug]);
}
```


Events
------

(since nette/application 2.4.11) In addition to methods `startup()`, `beforeRender()` and `shutdown()`, which are called as part of the presenter's life cycle, other functions can be defined to be called automatically. The presenter defines the so-called [events |nette:glossary#events], and you add their handlers to arrays `$onStartup` and `$onShutdown`.

```php
class ArticlePresenter extends Nette\Application\UI\Presenter
{
	public function __construct()
	{
		$this->onStartup[] = function () {
			// ...
		};
	}
}
```

Handlers in array `$onStartup` are called just before the method `startup()` and `$onShutdown` just before `shutdown()`.


Responses
---------

The response returned by the presenter is an object implementing the [api:Nette\Application\IResponse] interface. There are a number of ready-made answers:

- [api:Nette\Application\Responses\CallbackResponse] - sends a callback
- [api:Nette\Application\Responses\FileResponse] - sends the file
- [api:Nette\Application\Responses\ForwardResponse] - forward ()
- [api:Nette\Application\Responses\JsonResponse] - sends JSON
- [api:Nette\Application\Responses\RedirectResponse] - redirect
- [api:Nette\Application\Responses\TextResponse] - sends text
- [api:Nette\Application\Responses\VoidResponse] - blank response

Responses are sent by method `sendResponse()`:

```php
use Nette\Application\Responses;

// Plain text
$this->sendResponse(new Responses\TextResponse('Hello Nette!'));

// Sends a file
$this->sendResponse(new Responses\FileResponse(__DIR__ . '/invoice.pdf', 'Invoice13.pdf'));

// Sends a callback
$callback = function (Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse) {
	if ($httpResponse->getHeader('Content-Type') === 'text/html') {
		echo '<h1>Hello</h1>';
	}
};
$this->sendResponse(new Responses\CallbackResponse($callback));
```

Presenters

We will learn how to write presenters and templates in Nette. After reading you will know:

  • how the presenters works
  • what are persistent parameters
  • how to render a template

We already know that a presenter is a class that represents a specific page of a web application, such as a homepage; product in e-shop; sign-in form; sitemap feed, etc. The application can have from one to thousands of presenters. In other frameworks, they are also known as controllers.

Usually, the term presenter refers to a descendant of the class Nette\Application\UI\Presenter, which is suitable for web interfaces and which we will discuss in the rest of this chapter. In a general sense, a presenter is any object that implements the Nette\Application\IPresenter interface.

Life Cycle of Presenter

The job of the presenter is to process the request and return a response (which can be an HTML page, image, redirect, etc.).

So at the beginning is a request. It is not directly an HTTP request, but an Nette\Application\Request object into which the HTTP request was transformed using a router. We usually do not come into contact with this object, because the presenter cleverly delegates the processing of the request to special methods, which we will now see.

Life cycle of presenter

The figure shows a list of methods that are called sequentially from top to bottom, if they exists. None of them need to exist, we can have a completely empty presenter without a single method and build a simple static web on it.

__construct()

The constructor does not belong exactly to the life cycle of the presenter, because it is called at the moment of creating the object. But we mention it because of its importance. The constructor (together with method inject) is used to pass dependencies.

The presenter should not take care of the business logic of the application, write and read from the database, perform calculations, etc. This is the task for classes from a layer, which we call a model. For example, class ArticleRepository may be responsible for loading and saving articles. In order for the presenter to use it, it is passed using dependency injection:

class ArticlePresenter extends Nette\Application\UI\Presenter
{
	/** @var ArticleRepository */
	private $articles;

	public function __construct(ArticleRepository $articles)
	{
		$this->articles = $articles;
	}
}

startup()

Immediately after receiving the request, method startup () is invoked. You can use it to initialize properties, checks user privileges, etc. It is required to always call the parent::startup() ancestor.

action<Action>(args...)

Similar to the method render<View>(). While render<View>() is intended to prepare data for a specific template, which is subsequently rendered, in action<Action>() a request is processed without follow-up template rendering. For example, data is processed, a user is logged in or out, and so on, and then it redirects elsewhere.

It is important that action<Action>() is called before render<View>(), so inside it we can possibly change the next course of life cycle, ie. change the template that will be rendered and also the method render<View>() that will be called, using setView('otherView').

The parameters from the request are passed to the method. It is possible and recommended to specify types for the parameters by specifying their default value, eg actionShow($id = 0, $slug = '') – if parameter id is not an integer, the presenter returns error 404 and terminates the operation.

handle<Signal>(args...)

This method processes the so-called signals, which we will discuss in the chapter about Components. It is intended mainly for components and processing of AJAX requests.

The parameters are passed to the method, as in the case of action<Action>(), including type checking.

beforeRender()

Method beforeRender, as the name suggests, is called before each method render<View>(). Is used for common template configuration, passing variables for layout and so on.

render<View>(args...)

The place where we prepare the template for subsequent rendering, we pass data to it, etc.

The parameters are passed to the method, as in the case of action<Action>(), including type checking.

public function renderShow($id)
{
	// we obtain data from the model and pass it to the template
	$this->template->article = $this->articles->getById($id);
}

afterRender()

Method afterRender, as the name suggests again, is called after each render<View>() method. It is used rather rarely.

shutdown()

It is called at the end of the presenter's life cycle.

Good advice before we move on. As you can see, the presenter can handle more actions/views, ie have more methods render<View>(). But we recommend designing presenters with one or as few actions as possible.

Sending a Response

The presenter's response is usually rendering the template with the HTML page, but it can also be sending a file, JSON or even redirecting to another page.

At any time during the lifecycle, you can use any of the following methods to send a response and exit the presenter at the same time:

  • redirect(), redirectPermanent(), redirectUrl() and forward() redirects
  • error() quits presenter due to error
  • sendJson($data) quits presenter and sends the data in JSON format
  • sendTemplate() quits presenter and immediately renderes the template
  • sendResponse($response) quits presenter and sends own response
  • terminate() quits presenter without answer

If you do not call any of these methods, the presenter will automatically proceed to render the template. Why? Well, because in 99% of cases we want to draw a template, so the presenter takes this behavior as the default and wants to make our work easier.

Presenter has a method link(), which is used to create URL links to other presenters. The first parameter is the target presenter & action, followed by the arguments, which can be passed as array:

$url = $this->link('Product:show', $id);

$url = $this->link('Product:show', [$id, 'lang' => 'en']);

In template we create a links to other presenters & actions as follows:

<a n:href="Product:show $id">product detail</a>

Simply write the familiar Presenter:action pair instead of the real URL and include any parameters. The trick is n:href, which says that this attribute will be processed by Latte and generates a real URL. In Nette, you don't have to think about URLs at all, just about presenters and actions.

For more information, see Creating Links.

Redirection

Methods redirect() and forward() are used to jump to another presenter, which have a very similar syntax as the method link().

The forward() switches to the new presenter immediately without HTTP redirection:

$this->forward('Product:show');

Example of temporary redirection with HTTP code 302 or 303:

$this->redirect('Product:show', $id);

To achieve permanent redirection with HTTP code 301 use:

$this->redirectPermanent('Product:show', $id);

You can redirect to another URL outside the application with the redirectUrl() method:

$this->redirectUrl('https://nette.org');

Redirection immediately terminates the presenter's life cycle by throwing the so-called silent termination exception Nette\Application\AbortException.

Before redirection, it is possible to send a flash message, messages that will be displayed in the template after redirection.

Flash Messages

These are messages that usually inform about the result of an operation. An important feature of flash messages is that they are available in the template even after redirection. Even after being displayed, they will remain alive for another three seconds – for example, in case the user would unintentionally refresh the page – the message will not be lost.

Just call the flashMessage() method and presenter will take care of passing the message to the template. The first argument is the text of the message and the second optional argument is its type (error, warning, info etc.). The method flashMessage() returns an instance of flash message, to allow us to add more information.

$this->flashMessage('Item was removed.');
$this->redirect(/* ... */);

In the template, these messages are available in the variable $flashes as objects stdClass, which contain the properties message (message text), type (message type) and can contain the already mentioned user information. We draw them as follows:

{foreach $flashes as $flash}
	<div class="flash {$flash->type}">{$flash->message}</div>
{/foreach}

Error 404 etc.

When we can't fulfill the request because for example the article we want to display does not exist in the database, we will throw out the 404 error using method error(string $message = null, int $httpCode = 404), which represents HTTP error 404:

public function renderShow($id)
{
	$article = $this->articles->getById($id);
	if (!$article) {
		$this->error();
	}
	// ...
}

The HTTP error code can be passed as the second parameter, the default is 404. The method works by throwing exception Nette\Application\BadRequestException, after which Application passes control to the error-presenter. Which is a presenter whose job is to display a page informing about the error. The error-preseter is set in application configuration.

Sending JSON

Example of action-method that sends data in JSON format and exits the presenter:

public function actionData()
{
	$data = ['hello' => 'nette'];
	$this->sendJson($data);
}

Persistent Parameters

Persistent parameters are transferred automatically in links. This means that we do not have to explicitly specify them in every link() or n:href in the template, but they will still be transferred.

If your application has multiple language versions, then the current language is a parameter that must always be part of the URL. And it would be incredibly tiring to mention it in every link. That's not necessary with Nette. We simply mark the lang parameter as persistent in this way:

class ProductPresenter extends Nette\Application\UI\Presenter
{
	/** @persistent */
	public $lang;
}

If the current value of the parameter lang is 'en', then the URL created with link() or n:href in the template will contain lang=en. Great!

However, we can also add parameter lang and by that change its value:

<a n:href="Product:show $id, lang => en">detail in English</a>

Or, conversely, it can be removed by setting to null:

<a n:href="Product:show $id, lang => null">click here</a>

The persistent variable must be declared as public. We can also specify a default value. If the parameter has the same value as the default, it will not be included in the URL.

Persistence reflects the hierarchy of presenter classes, thus parameter defined in a certain presenter is then automatically transferred to each presenter inheriting from it.

Interactive Components

Presenters have a built-in component system. Components are separate reusable units that we place into presenters. They can be forms, datagrids, menus, in fact anything that makes sense to use repeatedly.

How are components placed and subsequently used in the presenter? This is explained in chapter Components. You'll even find out what they have to do with Hollywood.

Where Can I Get Some Components? On page Componette you can find some open-source components and other addons for Nette that are made and shared by the community of Nette Framework.

Going Deeper

What we have shown so far in this chapter will probably suffice. The following lines are intended for those who are interested in presenters in depth and want to know everything.

Requirement and Parameters

The request handled by the presenter is the Nette\Application\Request object and is returned by the presenter's method getRequest(). It includes an array of parameters and each of them belongs either to some of the components or directly to the presenter (which is actually also a component, albeit a special one). So Nette redistributes the parameters and passes between the individual components (and the presenter) by calling the method loadState(array $params), which is further described in the chapter Components. The parameters can be obtained by the method getParameters(): array, individually using getParameter($name). Parameter values ​​are strings or arrays of strings, they are basically raw data obtained directly from a URL.

Save and Restore the Request

You can save the current request to a session or restore it from the session and let the presenter execute it again. This is useful, for example, when a user fills out a form and it's login expires. In order not to lose data, before redirecting to the sign-in page, we save the current request to the session using $reqId = $this->storeRequest(), which returns an identifier in the form of a short string and passes it as a parameter to the sign-in presenter.

After sign in, we call the method $this->restoreRequest($reqId), which picks up the request from the session and forwards it to it. The method verifies that the request was created by the same user as now logged in is. If another user logs in or the key is invalid, it does nothing and the program continues.

Canonization

Presenters have one really great feature that improves SEO (optimization of searchability on the Internet). They automatically prevent the existence of duplicate content at different URLs. If multiple URLs lead to a certain destination, eg /index and /index?page=1, the framework designates one of them as the primary (canonical) and redirects the others to it using HTTP code 301. Thanks to this, search engines do not index pages twice and do not weaken their page rank.

This process is called canonization. The canonical URL is the URL generated by router, usually the first appropriate route in the collection.

Canonization is on by default and can be turned off via $this->autoCanonicalize = false.

Redirection does not occur with an AJAX or POST request because it would result in data loss or no SEO added value.

Since nette/application 2.4.6 you can also invoke canonization manually using method canonicalize(), which, like method link(), receives the presenter, actions, and parameters as arguments. It creates a link and compares it to the current URL. If it is different, it redirects to the generated link.

public function actionShow($id, $slug = null)
{
	$realSlug = $this->facade->getSlugForId($id);
	// redirects if $slug is different from $realSlug
	$this->canonicalize('Product:show', [$id, $realSlug]);
}

Events

(since nette/application 2.4.11) In addition to methods startup(), beforeRender() and shutdown(), which are called as part of the presenter's life cycle, other functions can be defined to be called automatically. The presenter defines the so-called events, and you add their handlers to arrays $onStartup and $onShutdown.

class ArticlePresenter extends Nette\Application\UI\Presenter
{
	public function __construct()
	{
		$this->onStartup[] = function () {
			// ...
		};
	}
}

Handlers in array $onStartup are called just before the method startup() and $onShutdown just before shutdown().

Responses

The response returned by the presenter is an object implementing the Nette\Application\IResponse interface. There are a number of ready-made answers:

Responses are sent by method sendResponse():

use Nette\Application\Responses;

// Plain text
$this->sendResponse(new Responses\TextResponse('Hello Nette!'));

// Sends a file
$this->sendResponse(new Responses\FileResponse(__DIR__ . '/invoice.pdf', 'Invoice13.pdf'));

// Sends a callback
$callback = function (Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse) {
	if ($httpResponse->getHeader('Content-Type') === 'text/html') {
		echo '<h1>Hello</h1>';
	}
};
$this->sendResponse(new Responses\CallbackResponse($callback));