Skip to content

Commit e943f13

Browse files
committed
Updated HTML frontend component docs
1 parent 106fe60 commit e943f13

File tree

2 files changed

+45
-89
lines changed

2 files changed

+45
-89
lines changed

src/frontend/html/create-subparts.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,37 @@ class Standard
4242

4343
public function body( $uid = '' ) : string
4444
{
45+
// optional
4546
}
4647

4748
public function header( $uid = '' ) : ?string
4849
{
50+
// optional
4951
}
5052

5153
public function getSubClient( string $type, string $name = null ) : \Aimeos\Client\Html\Iface
5254
{
55+
// optional
5356
}
5457

5558
protected function getSubClientNames() : array
5659
{
60+
// optional
61+
}
62+
63+
public function init()
64+
{
65+
// optional
66+
}
67+
68+
public function modify( string $content, string $uid ) : string
69+
{
70+
// optional
71+
}
72+
73+
public function data( Aimeos\MW\View\Iface $view, array &$tags = [], string &$expire = null ) : Aimeos\MW\View\Iface
74+
{
75+
// optional
5776
}
5877
}
5978
```

src/frontend/html/implement-components.md

Lines changed: 26 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -30,70 +30,40 @@ class Standard
3030
// optional
3131
}
3232

33-
public function init()
33+
public function getSubClient( string $type, string $name = null ) : \Aimeos\Client\Html\Iface
3434
{
3535
// optional
3636
}
3737

38-
public function getSubClient( string $type, string $name = null ) : \Aimeos\Client\Html\Iface
38+
protected function getSubClientNames() : array
3939
{
4040
// optional
4141
}
4242

43-
protected function getSubClientNames() : array
43+
public function init()
4444
{
4545
// optional
4646
}
47-
}
48-
```
49-
50-
Differences arise from the required code inside these methods as they have to care about caching (if you want to) and exception handling. A component can implement the same optional methods as any subpart. For a detailed description of these methods, please refer to the article about [creating new subparts](create-subparts.md#optional-methods).
5147

52-
The [getSubClient()](create-subparts.md#getSubClient) and [getSubClientNames()](create-subparts.md#getSubClientNames) methods are also exactly the same as in any other subpart and won't be described in this article again.
53-
54-
# init()
55-
56-
This method is not affected by caching at all because its purpose is to execute code once during each request. The difference to `init()` methods of subclients is only that you need to catch thrown exceptions and assign error messages to the view if necessary.
57-
58-
If you don't need to process any input in your new component, you can copy & paste the code below into your new class:
59-
60-
```php
61-
public function init()
62-
{
63-
$context = $this->context();
64-
$view = $this->view();
48+
public function modify()
49+
{
50+
// optional
51+
}
6552

66-
// your required code
67-
parent::init();
53+
public function data( Aimeos\MW\View\Iface $view, array &$tags = [], string &$expire = null ) : Aimeos\MW\View\Iface
54+
{
55+
// optional
56+
}
6857
}
6958
```
7059

71-
The only thing you have to **adapt is the name of the error list** assigned to the view. It should be named after your class name to something like `$view->...ErrorList`.
72-
73-
The cascade of `catch()` statements ensures that all exceptions are caught. Furthermore, all error messages translated that are passed to the view and shown to the customers. Unspecific exceptions are logged and only a generic error message is shown in the front-end to avoid giving away sensitive information.
74-
75-
You need to print these error messages in your component view which is described in the next section.
76-
77-
# Display error messages
78-
79-
The messages of the exceptions thrown in the different methods are assigned to the view using the `error` variable, which is an array of error messages. You need to add a snippet similar to this one at the top of your component body view:
80-
81-
```php
82-
<?php if( isset( $this->errors ) ) : ?>
83-
<ul class="error-list">
84-
<?php foreach( (array) $this->get( 'errors', [] ) as $errmsg ) : ?>
85-
<li class="error-item"><?= $this->encoder()->html( $errmsg ) ?></li>
86-
<?php endforeach ?>
87-
</ul>
88-
<?php endif ?>
89-
```
90-
These few lines of code create an HTML block that will contain all error messages. It will be styled by the used theme, so you don't have to care about this.
60+
A component can implement the same optional methods as any subpart. For a detailed description of these methods, please refer to the article about [creating new subparts](create-subparts.md#optional-methods).
9161

92-
# With content caching
62+
The [data()](create-subparts.md#data), [getSubClient()](create-subparts.md#getSubClient), [getSubClientNames()](create-subparts.md#getSubClientNames) and [modify()](create-subparts.md#modify) methods are also exactly the same as in any other subpart and won't be described in this article again.
9363

94-
Components that can cache its output are extremely fast. Once the content is generated and stored, it can be retrieved within milliseconds and directly pushed to the browser. The downside is that some additional code is needed.
64+
Differences arise from the required code inside these methods as they have to care about caching (if you want to). Components that can cache its output are extremely fast. Once the content is generated and stored, it can be retrieved within milliseconds and directly pushed to the browser. The downside is that some additional code is needed.
9565

96-
## body()
66+
# body()
9767

9868
When caching comes into play, the first thing you have to think about is: What does your output depend on? Usually, two external sources can influence what content needs to be generated: The request parameters and the configuration settings. Both has to be part of the cache key.
9969

@@ -129,7 +99,7 @@ The details for this are described in the article about [creating new subparts](
12999

130100
In doubt, have a look into a full example of a working [body() component method](https://github.com/aimeos/ai-client-html/blob/master/src/Client/Html/Catalog/Detail/Standard.php) which implements caching.
131101

132-
## header()
102+
# header()
133103

134104
For `header()`, implementing caching is very similar to the implementation of `body()`. You also have to specify which parameters are used in your component and what's the shared configuration prefix for all settings. The calls to `getCached()` and `setCached()` require "header" to be passed to ensure that the content is stored for the header.
135105

@@ -156,50 +126,17 @@ Only keep in mind that you also need to call the `modify()` method after success
156126

157127
In doubt, have a look into a full example of a working [header() component method](https://github.com/aimeos/ai-client-html/blob/master/src/Client/Html/Catalog/Detail/Standard.php) which implements caching.
158128

159-
# Factory class
129+
# Display error messages
160130

161-
All components are instantiated by factories which care about creating the HTML client and decorating it with additional classes added via configuration. The factory class is a rather simple piece of code that contains only a `create()` method:
131+
The messages of the exceptions thrown in the different methods are assigned to the view using the `error` variable, which is an array of error messages. You need to add a snippet similar to this one at the top of your component body view:
162132

163133
```php
164-
namespace Aimeos\Client\Html\Catalog\Detail;
165-
166-
class Factory
167-
extends \Aimeos\Client\Html\Common\Factory\Base
168-
implements \Aimeos\Client\Html\Common\Factory\Iface
169-
{
170-
public static function create( \Aimeos\MShop\Context\Item\Iface $context, array $paths, string $name = null ) : \Aimeos\Client\Html\Iface
171-
{
172-
if( $name null ) {
173-
$name = $context->config()->get( 'client/html/catalog/detail/name', 'Standard' );
174-
}
175-
176-
$iface = '\\Aimeos\\Client\\Html\\Iface';
177-
$classname = '\\Aimeos\\Client\\Html\\Catalog\\Detail\\' . $name;
178-
179-
if( ctype_alnum( $name ) === false ) {
180-
throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid characters in class name "%1$s"', $classname ) );
181-
}
182-
183-
$client = self::createClient( $context, $classname, $iface );
184-
$client = self::addClientDecorators( $context, $client, 'catalog/detail' );
185-
186-
return $client->setObject( $client );
187-
}
188-
}
189-
```
190-
191-
The code above is a factory for the catalog detail client. You can copy the code and replace the "Catalog\Detail" and "catalog/detail" strings with the name of your own component. For example, if you want to create a new "catalog homepage" component, you should replace the strings like this:
192-
193-
```
194-
Catalog\Detail -> Catalog\Homepage
195-
catalog/detail -> catalog/homepage
196-
```
197-
198-
Component factories for other purposes can created the same way, e.g. for a "basket upsell" component, replace the strings in that way:
199-
200-
```
201-
Catalog\Detail -> Basket\Upsell
202-
catalog/detail -> basket/upsell
134+
<?php if( isset( $this->errors ) ) : ?>
135+
<ul class="error-list">
136+
<?php foreach( (array) $this->get( 'errors', [] ) as $errmsg ) : ?>
137+
<li class="error-item"><?= $this->encoder()->html( $errmsg ) ?></li>
138+
<?php endforeach ?>
139+
</ul>
140+
<?php endif ?>
203141
```
204-
205-
The factory and the default implementation of your component must be saved to the appropriate directory, i.e. to the *./src/Catalog/Homepage* or *./src/Basket/Upsell* directory of your own extension.
142+
These few lines of code create an HTML block that will contain all error messages. It will be styled by the used theme, so you don't have to care about this.

0 commit comments

Comments
 (0)