Every widget needs TWO language keys
block_<key> and block_<key>_desc. Without them the AdminCP block picker lists raw key strings. Easy to ship without noticing, because the block itself renders fine.
Use ipsWidget markup, never your own ipsBox
The widget framework already supplies the box. Emitting ipsBox yourself nests a box inside a box and the header stops matching every other block on the page.
<div class="ipsWidget ipsWidget--vertical">
<h3 class="ipsWidget__header"> ... </h3>
<div class="ipsWidget__content"> ... </div>
</div>
A widget that throws leaves a cached blank
The static cache writes an empty placeholder before rendering, deliberately. If rendering throws, that blank persists even after the fault is fixed. Always clear caches after fixing a widget, or you will conclude your fix did not work.
Configuration is an empty array in two different situations
Before a block has ever been configured, and after saving it with nothing selected. So $this->configuration['x'] ?? $defaults is wrong: ?? only catches a missing key, not an empty one, and you get a permanently blank block. Fall through to defaults when the value is empty, not merely absent.
Test through __toString(), not render()
__toString() runs init(), _render() and the caching layer. Calling render() directly bypasses all of that and proves far less.
Recommended Comments