Widgets
Widgets are globally available placeholders provided by components.
How to create/register a widget
Any component can register any number of widgets. Widget names need to be unique across all components. Widgets are registered in postInit()
hook. Here's a simple widget registration example:
public function postInit(\Cx\Core\Core\Controller\Cx $cx) {
$this->getComponent('Widget')->registerWidget(
new \Cx\Core_Modules\Widget\Model\Entity\FinalStringWidget(
$this,
'MY_FIRST_WIDGET',
'Hello world'
)
);
}
This registers a widget that replaces the placeholder [[MY_SIMPLE_WIDGET]]
in the template/content by the string Hello world
.
Widget types
The widget type can be specified as an argument to the constructor of the widget class. To see which argument it is, please refer to the head of the constructor of the widget class in use.
Type | Description | Template-Format | Identifier |
---|---|---|---|
Placeholder
|
A widget of type placeholder is simply replaced by some content. | Placeholder widget names are written in uppercase. In the template it has the following format:
[[MY_PLACEHOLDER_WIDGET]] |
\Cx\Core_Modules\Widget\Model\Entity\Widget::TYPE_PLACEHOLDER
|
Block
|
A widget of type block has content, which can be altered while parsing the widget. The block is then replaced with the parsed content. | Block widget names are written in lowercase. In the template it has the following format:
<!-- START my_block_widget -->
any content
<!-- END my_block_widget -->
Everything between the start and the end tag is passed to the widget for parsing. |
\Cx\Core_Modules\Widget\Model\Entity\Widget::TYPE_BLOCK
|
Callback
|
A widget of type callback is like a placeholder with arguments. | Callback widget names are written in lowercase. In the template it has the following format:
func_my_callback_widget('foo', 'bar')
'foo' and 'bar' are passed to the widget render method as arguments. |
\Cx\Core_Modules\Widget\Model\Entity\Widget::TYPE_CALLBACK
|
Widget classes
Class | Description | Supported Types |
---|---|---|
FinalStringWidget
|
Use for static content | Placeholder
|
EsiWidget
|
Use for dynamic content | Placeholder / Block / Callback
|
RandomEsiWidget
|
Use for random content | Placeholder / Block / Callback
|
Final string widgets
Final string widgets are always of type Placeholder
. They are cached in the page cache. This means they should only be used for things which only change when the whole page they are used on changes. Two examples are:
-
[[CANONICAL_LINK]]
: Depends on the page, only changes when the page changes. If the page changes, the respective page cache is flushed anyway. -
[[PATH_OFFSET]]
: Path offset should never change on a live system. If it does, the whole page cache should be flushed in order to avoid problems.
ESI widgets
In order to circumvent the cache limitations of a FinalStringWidget
there are ESI widgets. ESI widgets are cached separately. Each ESI widget has its own cache lease time and its cache can be flushed individually (see Dropping EsiWidget Cache).
This is achieved by replacing ESI widgets (resp. their template-notation) by ESI element tags. The ESI element tags are then (before the response is sent back to the client) being replaced (by a reverse proxy or Cloudrexx itself) by the response of an Exposed method.
You can register your own EsiWidget
along with any other widget class in postInit()
of your ComponentController
. You'll then have to implement and register (see Add another controller) a new controller that inherits from \Cx\Core_Modules\Widget\Controller\EsiWidgetController
. Your own EsiWidgetController
must implement the method parseWidget()
which will then be used to fetch the content of your ESI widget.
ESI widget variables
ESI widget variables define on which information the widget depends. All necessary variables should be selected to ensure all necessary data is available for parsing. The less variables are selected, the more efficient the widget can be cached.
The selected data is passed to EsiWidgetController::parseWidget($name, $template, $response, $params)
method. $params['$key']
will contain Passed content from the listing below:
ESI variable ($key )
|
EsiWidget Constant | Description | Default if | Passed content | Short name [1] | |
---|---|---|---|---|---|---|
Type | Description | |||||
page
|
ESI_VAR_ID_PAGE
|
Widget depends on current page | ESI variables are not overwritten by setEsiVariables()
|
\Cx\Core\ContentManager\Model\Entity\Page
|
The resolved page the widget is located on | p
|
locale
|
ESI_VAR_ID_LOCALE
|
Widget depends on current locale | ESI variables are not overwritten by setEsiVariables()
|
\Cx\Core\Locale\Model\Entity\Locale
|
The locale of the resolved page | l
|
theme
|
ESI_VAR_ID_THEME
|
Widget depends on current theme | ESI variables are not overwritten by setEsiVariables() and widget type is block
|
\Cx\Core\View\Model\Entity\Theme
|
The resolved theme | t
|
channel
|
ESI_VAR_ID_CHANNEL
|
Widget depends on current channel | ESI variables are not overwritten by setEsiVariables() and widget type is block
|
string
|
The resolved channel. One of:
|
ch
|
user
|
ESI_VAR_ID_USER
|
Widget depends on session | - | string
|
The session-ID of the request | u
|
currency
|
ESI_VAR_ID_CURRENCY
|
Widget depends on current currency | - | string [2]
|
The currently set currency code (i.e. EUR )
|
c
|
country
|
ESI_VAR_ID_COUNTRY
|
Widget depends on current country | - | string [2]
|
The country the current request (its IP) originats from | g
|
path
|
ESI_VAR_ID_PAGE
|
Widget depends on current path | - | string
|
The path of the requested ressource | pa
|
query
|
ESI_VAR_ID_QUERY
|
Widget depends on current URL query arguments | - | array
|
The query string arguments of the requested ressource | q
|
ESI widget variables can be set on the EsiWidget instance by using setEsiVariables()
or setEsiVariable()
. \Cx\Core_Modules\Widget\Model\Entity\EsiWidget
provides the appropriate constants which can be combined using the bitwise OR
operation.
- Example
// create new block widget
$widget = new \Cx\Core_Modules\Widget\Model\Entity\EsiWidget(
$this,
'MY_FANCY_BLOCK_WIDGET',
\Cx\Core_Modules\Widget\Model\Entity\Widget::TYPE_BLOCK
);
// make widget locale-dependent
// note: $widget->setEsiVariable() does append an additional ESI-variable to the
// widget (in contrary to $widget->setEsiVariables(), which does overwrite
// existing variables).
$widget->setEsiVariable(
\Cx\Core_Modules\Widget\Model\Entity\EsiWidget::ESI_VAR_ID_LOCALE
);
// register block widget
$this->getComponent('Widget')->registerWidget($widget);
Set cache lease time
The default lease time for ESI widget equals the page cache lease time. The default cache lease time can be overwritten for each widget in EsiWidgetController::parseWidget() by setting an expiration date on the response:
$response->setExpirationDate(new \DateTime('+1hour')); // sets a maximum lease time of one hour
Clear cache
The cache of one or more ESI widgets can be cleared manually by calling:
$this->cx->getEvents()->triggerEvent(
'clearEsiCache',
array(
'Widget',
array(
'MY_FIRST_WIDGET',
'MY_SECOND_WIDGET',
),
)
);
References
Random ESI widgets
If one or more entries of a list should be shown, randomly changing for each request, then RandomEsiWidget
is the way to go. It basically works the same as a normal ESI widget, with the following differences:
- Use
setUniqueRepetitionCount()
to set the number of entries to show (default is 1) - Implement
\Cx\Core_Modules\Widget\Controller\RandomEsiWidgetController
instead of\Cx\Core_Modules\Widget\Controller\EsiWidgetController
- Use
RandomEsiWidgetController::getRandomEsiWidgetContentInfos($widgetName, $params, $template)
to return the list of available entries
Widget parsing
Widgets are parsed recursively. This means that widgets can be placed within the content of other widgets. However, a widget can never be placed within itself. If this is tried, the widget is simply not parsed.
Caching
If SSI/ESI-Caching is enabled, then the content of ESI widgets and Random ESI widgets is being cached. The cache is generated seperately for each resolved parse target. See Clear cache for flushing the cache of a widget.
Parse Targets
Widgets are parsed in the scope of so-called Parse Targets. A Parse Target represents a website element that contains HTML-code as well as Widgets. Currently there exist the following parse targets:
Parse Target | Description |
---|---|
\Cx\Core\View\Model\Entity\Theme
|
A functional HTML file of a webdesign template. This includes:
Note:
headlines.html , events.html , navbar.html , subnavbar.html , etc. are widgets on their own and can therefore also be used as container for other widgets as parsing is done recursively. |
\Cx\Core\ContentManager\Model\Entity\Page
|
Any page managed by the Content Manager |
\Cx\Modules\Block\Model\Entity\Block
|
Any content pane |
Implement your own Parse Target
To add your own parse target (i.e. an entity of your own component), your entity has to implement \Cx\Core_Module\Widget\Model\Entity\WidgetParseTarget
.
Then you could parse any widgets within your own parse target as follows:
$this->cx->getComponent('Widget')->parseWidgets(
$template, // Sigma template to parse
$this->getName(), // Name of the component your parse target belongs to
'<NameOfEntity>', // Name of your entity that is being used as parse target
$id // The resolved identifier of your entity that has been requested
);