Hi guys,
I’m in the process of building a site editor that allows admins to insert widgets onto a page dynamically.
The widgets available for dropping onto the page will be developed and maintained by developers of varying skill levels.
Currently I have a block of code which encapsulates the rendering of each section which contains a group of widgets inside a try/catch statement.
My problem is that if one of these widgets has a bug or hasn’t been configured correct it will throw some sort of exception/error.
When this happens I want to just display some text in place of that widget to the effect of "This block could not load" and then continue loading the rest of the page with all the other widgets.
At present when an error/exception is thrown it seems to halt the entire loading of the page rather than continuing the rendering process.
I’ve included the code below, just to clarify “Block” refers to the widget and “Section” refers to the container of the group of widgets. So a page would have a layout with multiple sections (named header-left, header-right, menu, above-content, below-content, footer etc.) which would contain multiple widgets / blocks (such as MainMenuBlock, HtmlBlock, BookListBlock etc.)
Layout would look like:
<html>
<body>
<div id="top">
<div class="container">
<div class="row">
<?= SectionWidget::widget([
'id' => 'header-left',
]); ?>
<?= SectionWidget::widget([
'id' => 'header-right',
]); ?>
</div>
<div class="row">
<?= SectionWidget::widget([
'name' => 'main-menu',
]); ?>
</div>
</div>
</div>
</body>
</html>
And then SectionWidget::widget would call renderBlocks() as seen below:
...
public function run()
{
$this->openTag();
$this->renderBlocks();
$this->closeTag();
}
public function renderBlocks()
{
$items = ConfigSiteBlocks::getBySectionNameAsArray($this->name);
$count = 0;
foreach ($items as $item)
{
try
{
// prepare config
$config = Json::decode($item['Config']);
// set id if not passed in via config
if (empty($config['id']))
{
$config['id'] = "block-".Inflector::camel2id($this->name)."-$count";
$count++;
}
// get instance of block
$block = Block::getInstance($item['ConfigSiteBlocksId'], $item['ConfigSiteSharedBlocksId'], $item['ClassName'], $config);
// render the block
$block->openTag();
$block->run();
$block->closeTag();
}
catch (Exception $e)
{
echo '<div>Block could not be loaded</div>';
}
}
}
...