There are two ways to put a custom block on an Elementor site, and the visa site used one of them, paste self-contained HTML into the HTML widget, fast, direct, done in an hour. The testimonial carousel deliberately took the other road, a real widget class with native controls, and this post is the honest comparison, because both are right, for different jobs, and knowing which is which saves either an hour or a month.
A real Elementor widget is a PHP class extending Widget_Base, and its heart is the controls it declares, which become the editing panel a client sees:
class Everse_Testimonial_Carousel extends ElementorWidget_Base {
public function get_name() { return 'everse_testimonials'; }
public function get_title() { return 'Testimonial Carousel'; }
public function get_icon() { return 'eicon-testimonial-carousel'; }
protected function register_controls() {
$this->start_controls_section('content', array('label' => 'Testimonials'));
$repeater = new ElementorRepeater();
$repeater->add_control('quote', array('type' => ElementorControls_Manager::TEXTAREA, 'label' => 'Quote'));
$repeater->add_control('name', array('type' => ElementorControls_Manager::TEXT, 'label' => 'Name'));
$repeater->add_control('role', array('type' => ElementorControls_Manager::TEXT, 'label' => 'Role or City'));
$repeater->add_control('photo', array('type' => ElementorControls_Manager::MEDIA, 'label' => 'Photo'));
$this->add_control('testimonials', array(
'type' => ElementorControls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
));
$this->end_controls_section();
// plus style sections: colors, typography, arrows, autoplay speed
}
}
The Repeater is the piece that decides the whole comparison, it gives editors an add-another-testimonial button, each entry a little form, reorder by drag, delete with a click. That is the difference in one control, with pasted HTML, adding a testimonial means someone edits markup, finds the right div, copies a block, and hopes, with the widget, a client adds their own quotes forever without asking me. The render method then loops the saved entries into the carousel markup, and every colour and font the style sections declare arrives as native Elementor styling tabs, the client restyles per site without touching CSS.
The honest decision rule the two roads taught me. Pasted HTML wins for one-off blocks on one site, static content, an hour of work, the visa site’s comparison table was exactly that and the choice was right. The widget class wins the moment any of three things is true, the content will change after launch, non-developers will manage it, or the block will live on more than one site. The carousel scored three for three, which is why it earned the month instead of the hour, and the month has repaid itself on every site since.
A few things people ask me about this
What is the minimum for a working Elementor widget? A class extending Widget_Base with get_name, get_title, register_controls, and render, registered inside elementor/widgets/register. Everything else, icons, categories, style tabs, is enrichment.
How do editors manage repeating items like testimonials? The Repeater control, define the fields once, Elementor provides the add, reorder, and delete interface, and render loops the saved array.
Next
The carousel still had to actually slide, and I did not write the sliding. Why a proven library beat my own animation code is the next post.
