почему эту логику не засунуть в функцию widget?

то есть у нас есть функция widget, абсолютно декларативная

   widget($some_element)

которая проверяет че там с элементом и делает то что нужно: либо возвращает new Widget, либо возвращает существующий