Nette Documentation Preview

syntax
Interactive Components
**********************

<div class=perex>

Components are separate reusable objects that we place into pages. They can be forms, datagrids, polls, in fact anything that makes sense to use repeatedly. We will show:

- how to use components?
- how to write them?
- What are signals?

</div>

Nette has a built-in component system. Older of you may remember something similar from Delphi or ASP.NET Web Forms. React or Vue.js is built on something remotely similar. However, in the world of PHP frameworks, this is a completely unique feature.

At the same time, components fundamentally change the approach to application development. You can compose pages from pre-prepared units. Do you need datagrid in administration? You can find it at [Componette |https://componette.org/search/component], a repository of open-source add-ons (not just components) for Nette, and simply paste it into the presenter.

You can incorporate any number of components into the presenter. And you can insert other components into some components. This creates a component tree with a presenter as a root.


Factory Methods
===============

How are components placed and subsequently used in the presenter? Usually using factory methods.

The component factory is an elegant way to create components only when they are really needed (lazy / on-demand). The whole magic is in implementation of a method called `createComponent<Name>()`, where `<Name>` is the name of the component, that will create and return.

```php .{file:DefaultPresenter.php}
class DefaultPresenter extends Nette\Application\UI\Presenter
{
	protected function createComponentPoll(): PollControl
	{
		$poll = new PollControl;
		$poll->items = $this->item;
		return $poll;
	}
}
```

Because all components are created in separate methods, the code is cleaner and easier to read.

.[note]
Component names always start with a lowercase letter, although they are capitalized in the method name.

We never call factories directly, they get called automatically, when we use components for the first time. Thanks to that, a component is created at the right moment, and only if it's really needed. If we wouldn't use the component (for example on some AJAX request, where we return only part of the page, or when parts are cached), it wouldn't even be created and we save performance of the server.

```php .{file:DefaultPresenter.php}
// we access the component and if it was the first time,
// it calls createComponentPoll() to create it
$poll = $this->getComponent('poll');
// alternative syntax: $poll = $this['poll'];
```

In the template, you can render a component using tag [{control} |#Rendering]. So there is no need of manually passing the components to template.

```latte
<h2>Please Vote</h2>

{control poll}
```


Hollywood Style
===============

Components commonly use one cool technique, which we like to call Hollywood style. Surely you know the cliché that actors hear often at the casting calls: "Don't call us, we'll call you." And that's what this is about.

In Nette, instead of having to constantly ask questions ("was the form submitted?", "was it valid?" or "did anyone press this button?"), you tell the framework "when this happens, call this method" and leave further work on it. If you program in JavaScript, you are familiar with this style of programming. You write functions that are called when a certain event occurs. And the engine passes the appropriate parameters to them.

This completely changes the way you write applications. The more tasks you can delegate to the framework, the less work you have. And the less you can forget.


How to Write a Component
========================

By component we usually mean descendants of the class [api:Nette\Application\UI\Control]. The presenter [api:Nette\Application\UI\Presenter] itself is also a descendant of the `Control` class.

```php .{file:PollControl.php}
use Nette\Application\UI\Control;

class PollControl extends Control
{
}
```


Rendering
=========

We already know that the `{control componentName}` tag is used to draw a component. It actually calls the method `render()` of the component, in which we take care of the rendering. We have, just like in the presenter, a [Latte |latte:] template in the variable `$this->template`, to which we pass the parameters. Unlike use in a presenter, we must specify a template file and let it render:

```php .{file:PollControl.php}
public function render(): void
{
	// we will put some parameters into the template
	$this->template->param = $value;
	// and draw it
	$this->template->render(__DIR__ . '/poll.latte');
}
```

The tag `{control}` allows to pass parameters to the method `render()`:

```latte
{control poll $id, $message}
```

```php .{file:PollControl.php}
public function render(int $id, string $message): void
{
	// ...
}
```

Sometimes a component can consist of several parts that we want to render separately. For each of them we will create own rendering method, here is for example `renderPaginator()`:

```php .{file:PollControl.php}
public function renderPaginator(): void
{
	// ...
}
```

And in the template we then call it using:

```latte
{control poll:paginator}
```

For better understanding it's good to know how the tag is compiled to PHP code.

```latte
{control poll}
{control poll:paginator 123, 'hello'}
```

This compiles to:

```php
$control->getComponent('poll')->render();
$control->getComponent('poll')->renderPaginator(123, 'hello');
```

`getComponent()` method returns the `poll` component and then the `render()` or `renderPaginator()` method, respectively, is called on it.

.[caution]
If anywhere in the parameter part **`=>`** is used, all parameters will be wrapped with an array and passed as the first argument:

```latte
{control poll, id => 123, message => 'hello'}
```

compiles to:

```php
$control->getComponent('poll')->render(['id' => 123, 'message' => 'hello']);
```

Rendering of sub-component:

```latte
{control cartControl-someForm}
```

compiles to:

```php
$control->getComponent("cartControl-someForm")->render();
```

Components, like presenters, pass several useful variables to templates automatically:

- `$basePath` is an absolute URL path to root dir (for example `/CD-collection`)
- `$baseUrl` is an absolute URL to root dir (for example `http://localhost/CD-collection`)
- `$user` is an object [representing the user |/security/authentication]
- `$presenter` is the current presenter
- `$control` is the current component
- `$flashes` list of [messages |#flash-messages] sent by method `flashMessage()`


Signal
======

We already know that navigation in the Nette application consists of linking or redirecting to pairs `Presenter:action`. But what if we just want to perform an action on the **current page**? For example, change the sorting order of the column in the table; delete item; switch light/dark mode; submit the form; vote in the poll; etc.

This type of request is called a signal. And like actions invoke methods `action<Action>()` or `render<Action>()`, signals call methods `handle<Signal>()`. While the concept of action (or view) relates only to presenters, signals apply to all components. And therefore also to presenters, because `UI\Presenter` is a descendant of `UI\Control`.

```php
public function handleClick(int $x, int $y): void
{
	// ... processing of signal ...
}
```

The link that calls the signal is created in the usual way, i.e. in the template by the attribute `n:href` or the tag `{link}`, in the code by the method `link()`. More in the chapter [Creating URL links |creating-links#Links to Signal].

```latte
<a n:href="click! $x, $y">click here</a>
```

The signal is always called on the current presenter and view, so it is not possible to link to signal in different presenter / action.

Thus, the signal causes the page to be reloaded in exactly the same way as in the original request, only in addition it calls the signal handling method with the appropriate parameters. If the method does not exist, exception [api:Nette\Application\UI\BadSignalException] is thrown, which is displayed to the user as error page 403 Forbidden.


Snippets and AJAX
=================

The signals may remind you a little bit AJAX: handlers that are called on the current page. And you're right, signals are really often called using AJAX, and then we only transmit changed parts of the page to the browser. They are called snippets. More information can be found on [the page about AJAX |ajax].


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

A component has its own storage of flash messages independent of the presenter. These are messages that, for example, inform about the result of the 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 30 seconds - for example, in case the user would unintentionally refresh the page - the message will not be lost.

Sending is done by the method [flashMessage |api:Nette\Application\UI\Control::flashMessage()]. The first parameter is the message text or the `stdClass` object representing the message. Optional second parameter is its type (error, warning, info, etc.). The method `flashMessage()` returns an instance of flash message as object stdClass to which you can pass information.

```php
$this->flashMessage('Item was deleted.');
$this->redirect(/* ... */); // and 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}
```


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

It is often needed to keep some parameter in a component for the whole time of working with the component. It can be for example the number of the page in pagination. This parameter should be marked as persistent using the annotation `@persistent`.

```php
class PollControl extends Control
{
	/** @persistent */
	public $page = 1;
}
```

This parameter will be automatically passed in every link as a `GET` parameter until the user leaves the page with this component.

.[caution]
Never trust persistent parameters blindly because they can be faked easily (by overwriting the URL). Verify, for example, if the page number is within the correct interval.

In PHP 8, you can also use attributes to mark persistent parameters:

```php
use Nette\Application\Attributes\Persistent;

class PollControl extends Control
{
	#[Persistent]
	public $page = 1;
}
```


Persistent Components
=====================

Not only parameters but also components can be persistent. Their persistent parameters are also transferred between different actions or between different presenters. We mark persistent components with this annotations for the presenter class. For example here we mark components `calendar` and `poll` as follows:

```php
/**
 * @persistent(calendar, poll)
 */
class DefaultPresenter extends Nette\Application\UI\Presenter
{
}
```

You don't have to mark subcomponents as persistent, they are persistent automatically.

In PHP 8, you can also use attributes to mark persistent components:

```php
use Nette\Application\Attributes\Persistent;

#[Persistent('calendar', 'poll')]
class DefaultPresenter extends Nette\Application\UI\Presenter
{
}
```


Components with Dependencies
============================

How to create components with dependencies without "messing up" the presenters that will use them? Thanks to the clever features of the DI container in Nette, as with using traditional services, we can leave most of the work to the framework.

Let's take as an example a component that has a dependency on the `PollFacade` service:

```php
class PollControl extends Control
{
	/** @var PollFacade */
	private $facade;

	/** @var int Id of a poll, for which the component is created */
	private $id;

	public function __construct(int $id, PollFacade $facade)
	{
		$this->facade = $facade;
		$this->id = $id;
	}

	public function handleVote(int $voteId): void
	{
		$this->facade->vote($id, $voteId);
		//...
	}
}
```

If we were writing a classic service, there would be nothing to worry about. The DI container would invisibly take care of passing all the dependencies. But we usually handle components by creating a new instance of them directly in the presenter in [#factory methods] `createComponent...()`. But passing all the dependencies of all the components to the presenter to then pass them to the components is cumbersome. And the amount of code written...

The logical question is, why don't we just register the component as a classic service, pass it to the presenter, and then return it in the `createComponent...()` method? But this approach is inappropriate because we want to be able to create the component multiple times.

The correct solution is to write a factory for the component, i.e. a class that creates the component for us:

```php
class PollControlFactory
{
	/** @var PollFacade */
	private $facade;

	public function __construct(PollFacade $facade)
	{
		$this->facade = $facade;
	}

	public function create(int $id): PollControl
	{
		return new PollControl($id, $this->facade);
	}
}
```

Now we register our service to DI container to configuration:

```neon
services:
	- PollControlFactory
```

Finally, we will use this factory in our presenter:

```php
class PollPresenter extends Nette\UI\Application\Presenter
{
	/** @var PollControlFactory */
	private $pollControlFactory;

	public function __construct(PollControlFactory $pollControlFactory)
	{
		$this->pollControlFactory = $pollControlFactory;
	}

	protected function createComponentPollControl(): PollControl
	{
		$pollId = 1; // we can pass our parameter
		return $this->pollControlFactory->create($pollId);
	}
}
```

The great thing is that Nette DI can [generate |/dependency-injection/factory] such simple factories, so instead of writing the whole code, you just need to write its interface:

```php
interface PollControlFactory
{
	public function create(int $id): PollControl;
}
```

That's all. Nette internally implements this interface and injects it to our presenter, where we can use it. It also magically passes our parameter `$id` and instance of class `PollFacade` into our component.


Advanced Use of Components
==========================

[* lifecycle-component.svg *] *** *Life cycle of components* .<>

Components are mostly renderable. But also unrenderable components exist. Some components can have descendants, some not. Nette Framework introduces several classes and interfaces for all these types of components.

Object inheritance allows us to have a hierarchic structure of classes like in real world. We can create new classes by extending. These extended classes are descendants of the original class and inherit its parameters and methods. Extended class can add its own parameters and methods to the inherited ones.

Knowledge class hierarchy is required for proper understanding how things work.

```
Nette\ComponentModel\Component  { IComponent }
|
+- Nette\ComponentModel\Container  { IContainer }
   |
   +- Nette\Application\UI\Component  { SignalReceiver, StatePersistent }
      |
      +- Nette\Application\UI\Control  { Renderable }
         |
         +- Nette\Application\UI\Presenter  { IPresenter }
```


Nette\ComponentModel\IComponent .{toc: IComponent}
--------------------------------------------------

Interface [api:Nette\ComponentModel\IComponent] has to be implemented by every component. It requires method `getName()` which is returning its name and `getParent()` returning its parent. Both name and parent can be set using method `setParent()` - first argument is parent and the second one is name.


Nette\ComponentModel\Component .{toc: Component}
------------------------------------------------

[api:Nette\ComponentModel\Component] is a standard implementation of `IComponent`. It is common ancestor of all components including form elements. It has several methods for traversing:

[lookup($type)|api:Nette\ComponentModel\Component::lookup()] looks up object of given class or interface up in the hierarchy. For example `$component->lookup(Nette\Application\UI\Presenter::class)` returns presenter if the components is bound to it (even deep in the hierarchy).

[lookupPath($type)|api:Nette\ComponentModel\Component::lookupPath()] returns path - a string made by concatenating names of all components on the way between current and component of `$type`. For example `$component->lookupPath(Nette\Application\UI\Presenter::class)` returns unique identifier of component toward presenter.


Nette\ComponentModel\IContainer .{toc: IContainer}
--------------------------------------------------

Parent components implement not just `IComponent` but also [api:Nette\ComponentModel\IContainer]. Interface which contains methods for adding, removing, getting and iteration over components. Such components can create hierarchy - presenters can contain forms and these forms can contain form inputs. Whole tree hierarchy of components is created by branches of `IContainer` objects and `IComponent` leafs.


Nette\ComponentModel\Container .{toc: Container}
------------------------------------------------

[api:Nette\ComponentModel\Container] is a standard implementation of `IContainer` interface. It is an ancestor of for example form or classes `Control` and `Presenter`.

It offers methods for correct adding, getting and removing objects and of course iteration over its contents. Attempt to call undefined child causes invoking of factory [createComponent($name)|api:Nette\ComponentModel\Container::createComponent()]. Method `createComponent($name)` invokes method `createComponent<component name>` in current component and it passes name of the component as a parameter. Created component is then passed to current component as its child. We call theese component factories, they can be implemented in classes inherited from `Container`.


Nette\Application\UI\Component .{toc: Component}
------------------------------------------------

Class [api:Nette\Application\UI\Component] is an ancestor of all components used in presenter. Components in presenter are object which are kept by presenter during its [life cycle |presenters#life-cycle-of-presenter].

They have ability to influence each other, save their states into URL and respond to user commands (signals) and does not have to be renderable.


Nette\Application\UI\Control .{toc: Control}
--------------------------------------------

[Control |api:Nette\Application\UI\Control] is a renderable component. It is a reusable part of web application which is this whole chapter about. When talking about components this is the class we usually have on mind. It remembers which part should be rendered in [AJAX request |ajax#invalidation], which [we've already talked about|#invalidation and snippets].

`Control` isn't representing visual sector of webpage, but its logical part. It is possible to render it repeatedly, conditionally and every time with different template.


Monitoring of Ancestors
-----------------------

Component model in Nette offers very dynamical tree workflow (components can be removed, added, moved). It would be a mistake to rely on knowing parent (in constructor) when the component is created. In most cases, parent is not known when the component is created.

How to find out when was component added to presenter's tree? Watching the change of parent is not enough because a parent of parent might have been added to presenter. Method [monitor($type, $attached, $detached)|api:Nette\ComponentModel\Component::monitor()] is here to help. Every component can monitor any number of classes and interfaces. Adding or removing is reported by invoking callback `$attached` (`$detached` respectivelly), where the object of monitored class is passed.

An example: Class `UploadControl`, representing form element for uploading files in Nette Forms, has to set form's attribute `enctype` to value `multipart/form-data`. But in the time of the creation of the object it does not have to be attached to any form. When to modify the form? The solution is simple - we create a request for monitoring in the constructor:

```php
class UploadControl extends Nette\Forms\Controls\BaseControl
{
	public function __construct($label)
	{
		$this->monitor(Nette\Forms\Form::class, function ($form): void {
			$form->setHtmlAttribute('enctype', 'multipart/form-data');
		});
		// ...
	}

	// ...
}
```

and when the form is available callback is called. (Formerly methods `attached` or `detached` was used instead).


Iterating over Children
-----------------------

There is a method [getComponents($deep = false, $type = null)|api:Nette\ComponentModel\Container::getComponents()] for that. First parameter determines if the components should be looked up in depth (recursively). With `true`, it not only iterates all its children, but also all children of its children, etc. Second parameter servers as an optional filter by class or interface.

For example, this is the way how validation of forms is "internally"((this is done by framework itself, you don't have to call it explicitly)) performed:

```php
$valid = true;
foreach ($form->getComponents(true, Nette\Forms\IControl::class) as $control) {
	if (!$control->getRules()->validate()) {
		$valid = false;
		break;
	}
}
```


Signals in Depth
----------------

A signal causes a page reload like the original request (with the exception of AJAX) and invokes the method `signalReceived($signal)` whose default implementation in class `Nette\Application\UI\Component` tries to call a method composed of the words `handle{Signal}`. Further processing relies on the given object. Objects which are descendants of `Component` (i.e. `Control` and `Presenter`) try to call `handle{Signal}` with relevant parameters.

In other words: the definition of the method `handle{Signal}` is taken and all parameters which were received in the request are matched with the method's parameters. It means that the parameter `id` from the URL is matched to the method's parameter `$id`, `something` to `$something` and so on. And if the method doesn't exist, the method `signalReceived` throws [an exception |api:Nette\Application\UI\BadSignalException].

Signal can be received by any component, presenter of object which implements interface `SignalReceiver` if it's connected to component tree.

The main receivers of signals are `Presenters` and visual components extending `Control`. A signal is a sign for an object that it has to do something - poll counts in a vote from user, box with news has to unfold, form was sent and has to process data and so on.

The URL for the signal is created using the method [Component::link() |api:Nette\Application\UI\Component::link()]. As parameter `$destination` we pass string `{signal}!` and as `$args` an array of arguments which we want to pass to the signal handler. Signal parameters are attached to the URL of the current presenter/view. **The parameter `?do` in the URL determines the signal called.**

Its format is `{signal}` or `{signalReceiver}-{signal}`. `{signalReceiver}` is the name of the component in the presenter. This is why hyphen (inaccurately dash) can't be present in the name of components - it is used to divide the name of the component and signal, but it's possible to compose several components.

The method [isSignalReceiver()|api:Nette\Application\UI\Presenter::isSignalReceiver()] verifies whether a component (first argument) is a receiver of a signal (second argument). The second argument can be omitted - then it finds out if the component is a receiver of any signal. If the second parameter is `true` it verifies whether the component or its descendants are receivers of a signal.

In any phase preceding `handle{Signal}` can be signal performed manually by calling the method [processSignal()|api:Nette\Application\UI\Presenter::processSignal()] which takes responsibility for signal execution. Takes receiver component (if not set it is presenter itself) and sends it the signal.

Example:

```php
if ($this->isSignalReceiver($this, 'paging') || $this->isSignalReceiver($this, 'sorting')) {
	$this->processSignal();
}
```

The signal is executed prematurely and it won't be called again.



/--comment
A signal causes a page reload like the original request (with the exception of AJAX) and invokes the method `signalReceived($signal)` whose default implementation in class `Nette\Application\UI\Component` tries to call a method composed of the words `handle{Signal}`. Further processing relies on the given object. Objects which are descendants of `Component` (i.e. `Control` and `Presenter`) try to call `handle{Signal}` with relevant parameters.
\--

{{composer: nette/application}}

Interactive Components

Components are separate reusable objects that we place into pages. They can be forms, datagrids, polls, in fact anything that makes sense to use repeatedly. We will show:

  • how to use components?
  • how to write them?
  • What are signals?

Nette has a built-in component system. Older of you may remember something similar from Delphi or ASP.NET Web Forms. React or Vue.js is built on something remotely similar. However, in the world of PHP frameworks, this is a completely unique feature.

At the same time, components fundamentally change the approach to application development. You can compose pages from pre-prepared units. Do you need datagrid in administration? You can find it at Componette, a repository of open-source add-ons (not just components) for Nette, and simply paste it into the presenter.

You can incorporate any number of components into the presenter. And you can insert other components into some components. This creates a component tree with a presenter as a root.

Factory Methods

How are components placed and subsequently used in the presenter? Usually using factory methods.

The component factory is an elegant way to create components only when they are really needed (lazy / on-demand). The whole magic is in implementation of a method called createComponent<Name>(), where <Name> is the name of the component, that will create and return.

class DefaultPresenter extends Nette\Application\UI\Presenter
{
	protected function createComponentPoll(): PollControl
	{
		$poll = new PollControl;
		$poll->items = $this->item;
		return $poll;
	}
}

Because all components are created in separate methods, the code is cleaner and easier to read.

Component names always start with a lowercase letter, although they are capitalized in the method name.

We never call factories directly, they get called automatically, when we use components for the first time. Thanks to that, a component is created at the right moment, and only if it's really needed. If we wouldn't use the component (for example on some AJAX request, where we return only part of the page, or when parts are cached), it wouldn't even be created and we save performance of the server.

// we access the component and if it was the first time,
// it calls createComponentPoll() to create it
$poll = $this->getComponent('poll');
// alternative syntax: $poll = $this['poll'];

In the template, you can render a component using tag {control}. So there is no need of manually passing the components to template.

<h2>Please Vote</h2>

{control poll}

Hollywood Style

Components commonly use one cool technique, which we like to call Hollywood style. Surely you know the cliché that actors hear often at the casting calls: „Don't call us, we'll call you.“ And that's what this is about.

In Nette, instead of having to constantly ask questions („was the form submitted?“, „was it valid?“ or „did anyone press this button?“), you tell the framework „when this happens, call this method“ and leave further work on it. If you program in JavaScript, you are familiar with this style of programming. You write functions that are called when a certain event occurs. And the engine passes the appropriate parameters to them.

This completely changes the way you write applications. The more tasks you can delegate to the framework, the less work you have. And the less you can forget.

How to Write a Component

By component we usually mean descendants of the class Nette\Application\UI\Control. The presenter Nette\Application\UI\Presenter itself is also a descendant of the Control class.

use Nette\Application\UI\Control;

class PollControl extends Control
{
}

Rendering

We already know that the {control componentName} tag is used to draw a component. It actually calls the method render() of the component, in which we take care of the rendering. We have, just like in the presenter, a Latte template in the variable $this->template, to which we pass the parameters. Unlike use in a presenter, we must specify a template file and let it render:

public function render(): void
{
	// we will put some parameters into the template
	$this->template->param = $value;
	// and draw it
	$this->template->render(__DIR__ . '/poll.latte');
}

The tag {control} allows to pass parameters to the method render():

{control poll $id, $message}
public function render(int $id, string $message): void
{
	// ...
}

Sometimes a component can consist of several parts that we want to render separately. For each of them we will create own rendering method, here is for example renderPaginator():

public function renderPaginator(): void
{
	// ...
}

And in the template we then call it using:

{control poll:paginator}

For better understanding it's good to know how the tag is compiled to PHP code.

{control poll}
{control poll:paginator 123, 'hello'}

This compiles to:

$control->getComponent('poll')->render();
$control->getComponent('poll')->renderPaginator(123, 'hello');

getComponent() method returns the poll component and then the render() or renderPaginator() method, respectively, is called on it.

If anywhere in the parameter part => is used, all parameters will be wrapped with an array and passed as the first argument:

{control poll, id => 123, message => 'hello'}

compiles to:

$control->getComponent('poll')->render(['id' => 123, 'message' => 'hello']);

Rendering of sub-component:

{control cartControl-someForm}

compiles to:

$control->getComponent("cartControl-someForm")->render();

Components, like presenters, pass several useful variables to templates automatically:

  • $basePath is an absolute URL path to root dir (for example /CD-collection)
  • $baseUrl is an absolute URL to root dir (for example http://localhost/CD-collection)
  • $user is an object representing the user
  • $presenter is the current presenter
  • $control is the current component
  • $flashes list of messages sent by method flashMessage()

Signal

We already know that navigation in the Nette application consists of linking or redirecting to pairs Presenter:action. But what if we just want to perform an action on the current page? For example, change the sorting order of the column in the table; delete item; switch light/dark mode; submit the form; vote in the poll; etc.

This type of request is called a signal. And like actions invoke methods action<Action>() or render<Action>(), signals call methods handle<Signal>(). While the concept of action (or view) relates only to presenters, signals apply to all components. And therefore also to presenters, because UI\Presenter is a descendant of UI\Control.

public function handleClick(int $x, int $y): void
{
	// ... processing of signal ...
}

The link that calls the signal is created in the usual way, i.e. in the template by the attribute n:href or the tag {link}, in the code by the method link(). More in the chapter Creating URL links.

<a n:href="click! $x, $y">click here</a>

The signal is always called on the current presenter and view, so it is not possible to link to signal in different presenter / action.

Thus, the signal causes the page to be reloaded in exactly the same way as in the original request, only in addition it calls the signal handling method with the appropriate parameters. If the method does not exist, exception Nette\Application\UI\BadSignalException is thrown, which is displayed to the user as error page 403 Forbidden.

Snippets and AJAX

The signals may remind you a little bit AJAX: handlers that are called on the current page. And you're right, signals are really often called using AJAX, and then we only transmit changed parts of the page to the browser. They are called snippets. More information can be found on the page about AJAX.

Flash Messages

A component has its own storage of flash messages independent of the presenter. These are messages that, for example, inform about the result of the 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 30 seconds – for example, in case the user would unintentionally refresh the page – the message will not be lost.

Sending is done by the method flashMessage. The first parameter is the message text or the stdClass object representing the message. Optional second parameter is its type (error, warning, info, etc.). The method flashMessage() returns an instance of flash message as object stdClass to which you can pass information.

$this->flashMessage('Item was deleted.');
$this->redirect(/* ... */); // and 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}

Persistent Parameters

It is often needed to keep some parameter in a component for the whole time of working with the component. It can be for example the number of the page in pagination. This parameter should be marked as persistent using the annotation @persistent.

class PollControl extends Control
{
	/** @persistent */
	public $page = 1;
}

This parameter will be automatically passed in every link as a GET parameter until the user leaves the page with this component.

Never trust persistent parameters blindly because they can be faked easily (by overwriting the URL). Verify, for example, if the page number is within the correct interval.

In PHP 8, you can also use attributes to mark persistent parameters:

use Nette\Application\Attributes\Persistent;

class PollControl extends Control
{
	#[Persistent]
	public $page = 1;
}

Persistent Components

Not only parameters but also components can be persistent. Their persistent parameters are also transferred between different actions or between different presenters. We mark persistent components with this annotations for the presenter class. For example here we mark components calendar and poll as follows:

/**
 * @persistent(calendar, poll)
 */
class DefaultPresenter extends Nette\Application\UI\Presenter
{
}

You don't have to mark subcomponents as persistent, they are persistent automatically.

In PHP 8, you can also use attributes to mark persistent components:

use Nette\Application\Attributes\Persistent;

#[Persistent('calendar', 'poll')]
class DefaultPresenter extends Nette\Application\UI\Presenter
{
}

Components with Dependencies

How to create components with dependencies without „messing up“ the presenters that will use them? Thanks to the clever features of the DI container in Nette, as with using traditional services, we can leave most of the work to the framework.

Let's take as an example a component that has a dependency on the PollFacade service:

class PollControl extends Control
{
	/** @var PollFacade */
	private $facade;

	/** @var int Id of a poll, for which the component is created */
	private $id;

	public function __construct(int $id, PollFacade $facade)
	{
		$this->facade = $facade;
		$this->id = $id;
	}

	public function handleVote(int $voteId): void
	{
		$this->facade->vote($id, $voteId);
		//...
	}
}

If we were writing a classic service, there would be nothing to worry about. The DI container would invisibly take care of passing all the dependencies. But we usually handle components by creating a new instance of them directly in the presenter in factory methods createComponent...(). But passing all the dependencies of all the components to the presenter to then pass them to the components is cumbersome. And the amount of code written…

The logical question is, why don't we just register the component as a classic service, pass it to the presenter, and then return it in the createComponent...() method? But this approach is inappropriate because we want to be able to create the component multiple times.

The correct solution is to write a factory for the component, i.e. a class that creates the component for us:

class PollControlFactory
{
	/** @var PollFacade */
	private $facade;

	public function __construct(PollFacade $facade)
	{
		$this->facade = $facade;
	}

	public function create(int $id): PollControl
	{
		return new PollControl($id, $this->facade);
	}
}

Now we register our service to DI container to configuration:

services:
	- PollControlFactory

Finally, we will use this factory in our presenter:

class PollPresenter extends Nette\UI\Application\Presenter
{
	/** @var PollControlFactory */
	private $pollControlFactory;

	public function __construct(PollControlFactory $pollControlFactory)
	{
		$this->pollControlFactory = $pollControlFactory;
	}

	protected function createComponentPollControl(): PollControl
	{
		$pollId = 1; // we can pass our parameter
		return $this->pollControlFactory->create($pollId);
	}
}

The great thing is that Nette DI can generate such simple factories, so instead of writing the whole code, you just need to write its interface:

interface PollControlFactory
{
	public function create(int $id): PollControl;
}

That's all. Nette internally implements this interface and injects it to our presenter, where we can use it. It also magically passes our parameter $id and instance of class PollFacade into our component.

Advanced Use of Components

Life cycle of components

Components are mostly renderable. But also unrenderable components exist. Some components can have descendants, some not. Nette Framework introduces several classes and interfaces for all these types of components.

Object inheritance allows us to have a hierarchic structure of classes like in real world. We can create new classes by extending. These extended classes are descendants of the original class and inherit its parameters and methods. Extended class can add its own parameters and methods to the inherited ones.

Knowledge class hierarchy is required for proper understanding how things work.

Nette\ComponentModel\Component  { IComponent }
|
+- Nette\ComponentModel\Container  { IContainer }
   |
   +- Nette\Application\UI\Component  { SignalReceiver, StatePersistent }
      |
      +- Nette\Application\UI\Control  { Renderable }
         |
         +- Nette\Application\UI\Presenter  { IPresenter }

Nette\ComponentModel\IComponent

Interface Nette\ComponentModel\IComponent has to be implemented by every component. It requires method getName() which is returning its name and getParent() returning its parent. Both name and parent can be set using method setParent() – first argument is parent and the second one is name.

Nette\ComponentModel\Component

Nette\ComponentModel\Component is a standard implementation of IComponent. It is common ancestor of all components including form elements. It has several methods for traversing:

lookup($type) looks up object of given class or interface up in the hierarchy. For example $component->lookup(Nette\Application\UI\Presenter::class) returns presenter if the components is bound to it (even deep in the hierarchy).

lookupPath($type) returns path – a string made by concatenating names of all components on the way between current and component of $type. For example $component->lookupPath(Nette\Application\UI\Presenter::class) returns unique identifier of component toward presenter.

Nette\ComponentModel\IContainer

Parent components implement not just IComponent but also Nette\ComponentModel\IContainer. Interface which contains methods for adding, removing, getting and iteration over components. Such components can create hierarchy – presenters can contain forms and these forms can contain form inputs. Whole tree hierarchy of components is created by branches of IContainer objects and IComponent leafs.

Nette\ComponentModel\Container

Nette\ComponentModel\Container is a standard implementation of IContainer interface. It is an ancestor of for example form or classes Control and Presenter.

It offers methods for correct adding, getting and removing objects and of course iteration over its contents. Attempt to call undefined child causes invoking of factory createComponent($name). Method createComponent($name) invokes method createComponent<component name> in current component and it passes name of the component as a parameter. Created component is then passed to current component as its child. We call theese component factories, they can be implemented in classes inherited from Container.

Nette\Application\UI\Component

Class Nette\Application\UI\Component is an ancestor of all components used in presenter. Components in presenter are object which are kept by presenter during its life cycle.

They have ability to influence each other, save their states into URL and respond to user commands (signals) and does not have to be renderable.

Nette\Application\UI\Control

Control is a renderable component. It is a reusable part of web application which is this whole chapter about. When talking about components this is the class we usually have on mind. It remembers which part should be rendered in AJAX request, which we've already talked about.

Control isn't representing visual sector of webpage, but its logical part. It is possible to render it repeatedly, conditionally and every time with different template.

Monitoring of Ancestors

Component model in Nette offers very dynamical tree workflow (components can be removed, added, moved). It would be a mistake to rely on knowing parent (in constructor) when the component is created. In most cases, parent is not known when the component is created.

How to find out when was component added to presenter's tree? Watching the change of parent is not enough because a parent of parent might have been added to presenter. Method monitor($type, $attached, $detached) is here to help. Every component can monitor any number of classes and interfaces. Adding or removing is reported by invoking callback $attached ($detached respectivelly), where the object of monitored class is passed.

An example: Class UploadControl, representing form element for uploading files in Nette Forms, has to set form's attribute enctype to value multipart/form-data. But in the time of the creation of the object it does not have to be attached to any form. When to modify the form? The solution is simple – we create a request for monitoring in the constructor:

class UploadControl extends Nette\Forms\Controls\BaseControl
{
	public function __construct($label)
	{
		$this->monitor(Nette\Forms\Form::class, function ($form): void {
			$form->setHtmlAttribute('enctype', 'multipart/form-data');
		});
		// ...
	}

	// ...
}

and when the form is available callback is called. (Formerly methods attached or detached was used instead).

Iterating over Children

There is a method getComponents($deep = false, $type = null) for that. First parameter determines if the components should be looked up in depth (recursively). With true, it not only iterates all its children, but also all children of its children, etc. Second parameter servers as an optional filter by class or interface.

For example, this is the way how validation of forms is internally performed:

$valid = true;
foreach ($form->getComponents(true, Nette\Forms\IControl::class) as $control) {
	if (!$control->getRules()->validate()) {
		$valid = false;
		break;
	}
}

Signals in Depth

A signal causes a page reload like the original request (with the exception of AJAX) and invokes the method signalReceived($signal) whose default implementation in class Nette\Application\UI\Component tries to call a method composed of the words handle{Signal}. Further processing relies on the given object. Objects which are descendants of Component (i.e. Control and Presenter) try to call handle{Signal} with relevant parameters.

In other words: the definition of the method handle{Signal} is taken and all parameters which were received in the request are matched with the method's parameters. It means that the parameter id from the URL is matched to the method's parameter $id, something to $something and so on. And if the method doesn't exist, the method signalReceived throws an exception.

Signal can be received by any component, presenter of object which implements interface SignalReceiver if it's connected to component tree.

The main receivers of signals are Presenters and visual components extending Control. A signal is a sign for an object that it has to do something – poll counts in a vote from user, box with news has to unfold, form was sent and has to process data and so on.

The URL for the signal is created using the method Component::link(). As parameter $destination we pass string {signal}! and as $args an array of arguments which we want to pass to the signal handler. Signal parameters are attached to the URL of the current presenter/view. The parameter ?do in the URL determines the signal called.

Its format is {signal} or {signalReceiver}-{signal}. {signalReceiver} is the name of the component in the presenter. This is why hyphen (inaccurately dash) can't be present in the name of components – it is used to divide the name of the component and signal, but it's possible to compose several components.

The method isSignalReceiver() verifies whether a component (first argument) is a receiver of a signal (second argument). The second argument can be omitted – then it finds out if the component is a receiver of any signal. If the second parameter is true it verifies whether the component or its descendants are receivers of a signal.

In any phase preceding handle{Signal} can be signal performed manually by calling the method processSignal() which takes responsibility for signal execution. Takes receiver component (if not set it is presenter itself) and sends it the signal.

Example:

if ($this->isSignalReceiver($this, 'paging') || $this->isSignalReceiver($this, 'sorting')) {
	$this->processSignal();
}

The signal is executed prematurely and it won't be called again.