Building add-ons and widgets
Add-ons and widgets are lighter ways to extend the site than modules.
- Add-ons: hook into the processing of every request to add behavior (counters, auto-linking, nickname badges, etc.)
- Widgets: content pieces you can drop anywhere in a layout or page (login box, latest posts, etc.)
Building an add-on
addons/myaddon/
├── conf/info.xml ← 이름·설명·설정 항목
└── myaddon.addon.php ← 본체myaddon.addon.php is called at several points during request processing. Use the $called_position variable to tell which point you're at.
<?php
if (!defined('__XE__'))
{
exit();
}
// 화면 HTML이 완성되기 직전에 한 번 실행
if ($called_position === 'before_display_content'
&& Context::getResponseMethod() === 'HTML'
&& Context::get('module') !== 'admin'
&& !isCrawler())
{
// $output 변수에 완성된 HTML이 들어 있고, 수정하면 그대로 반영됩니다
$output = str_replace('%FOO%', '바꿀 내용', $output);
}Main call points:
| $called_position | When |
|---|---|
before_module_init | Before the module is prepared to run |
before_module_proc | Right before the action runs |
after_module_proc | Right after the action runs |
before_display_content | Right before the final HTML is output ($output can be modified) |
Things to watch out for:
- Add-ons run on almost every request. Do heavy work (DB queries, etc.) only after narrowing the conditions as much as possible, and cache the results.
- It's usually safest to skip the admin screen (
Context::get('module') === 'admin') and non-HTML responses (JSON, etc.). - If you declare
<extra_vars>inconf/info.xml, you can receive values in the admin add-on settings and read them in the main file with$addon_info->{var_name}.
Add-ons are turned on and off from the add-on list in the admin screen. You can set PC and mobile separately.
Building a widget
widgets/mywidget/
├── conf/info.xml ← 이름·설명·설정 항목(extra_vars)
├── mywidget.class.php ← 본체
└── skins/default/ ← 위젯 스킨
├── skin.xml
└── widget.htmlThe main file extends WidgetHandler, and the file name and class name must match the widget name.
<?php
class mywidget extends WidgetHandler
{
/**
* info.xml의 extra_vars 값이 $args로 들어옵니다.
* 결과 HTML을 출력하지 말고 반환해야 합니다.
*/
function proc($args)
{
$list = $this->getMyList((int)($args->count ?? 5));
Context::set('list', $list);
Context::set('colorset', $args->colorset);
$tpl_path = sprintf('%sskins/%s', $this->widget_path, $args->skin);
$oTemplate = TemplateHandler::getInstance();
return $oTemplate->compile($tpl_path, 'widget');
}
}- Settings declared with
<extra_vars>inconf/info.xmlbecome the fields entered on the widget insertion screen. - Skins work the same way as module skins. Compile the template in the skin folder selected by
$args->skinand return it. - Return the result; don't echo it. Widgets are joined as strings while the page is assembled.
Where widgets are used
- Inserted from the widget placement screen of layouts and pages
- Directly in template v2:
@widget('mywidget', $args) - The widget insertion feature in the editor body
Which one to build
| What you want | Tool |
|---|---|
| Automatic behavior on every page (display, replacement, logging) | Add-on |
| A content box the admin drops wherever they want | Widget |
| A feature with its own data, screens, and settings | Module |