Skip to content

How to create recent posts widget for Elementor – part 1

  • Last updated: May 7, 2020
recent posts widget for Elementor

Introduction

This is going to be a series of tutorial of making a recent posts widget for Elementor. I shall explain it in details so that everyone can easily understand and apply in their projects when needed.

As we know, Elementor is becoming one of the essential page builder plugin for WordPress. Thousands of websites today is using Elementor as an integrated part of their website. Personally I prefer it for creating pages. However, the Gutenberg is preferred for the posts. We will discuss about custom Gutenberg blocks with ACF in my upcoming tutorials.


The Concept and Basics

Every theme and plugin comes with it’s own property and functionality. But there can be some personal demand for new functionality which is not always a global need. For example, your client may require some new widgets for Elementor or any of your website may require some new widgets. Then we need to extend the plugin or theme with our own code. There may be free plugins available in the market but it is always wise to make your own and limit the third party dependency.

Whenever you are trying to extend a plugin functionality, always prefer writing a custom plugin for that. It’s more like add on. Here we are going to make a dynamic recent posts widget for Elementor with a new plugin called “Tartist Elementor Extension”. Those who are not familiar about how to write a plugin, I strongly recommend them to read this article first and gain basic concepts of making a plugin.

  1. How to write a plugin (codex help)
  2. Writing a simple plugin

Let’s jump into the code now. Make sure you have Elementor installed and activated.

Create the plugin

First, make a folder called “tartist-elementor-extension” in your plugins directory. Then create a blank php file named “tartist-elementor-extension.php”. After that, add the following skeleton code for the plugin so that WordPress can recognize the plugin.

<?php
/*
Plugin Name: Tartist Elementor Extension
Plugin URI: https://templateartist.com/
Description: Extendes Elementor and creates custom widgets.
Version: 1.0.0
Author: Amit Biswas
Author URI: https://templateartist.com
License: GPLv2 and later
Text Domain: tartist-elementor-extension
Domain Path: /languages/

Copyright YEAR PLUGIN_AUTHOR_NAME (email : your email address)
(Plugin Name) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
any later version.
 
(Plugin Name) is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with (Plugin Name). If not, see (http://link to your plugin license).
*/

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

You may now see your plugin at WordPress admin’s plugins page. Please activate the plugin and we are ready to move forward then.

Elementor class for making the extension

At this point, we can start using a class provided by Elementor for custom plugins that extends it. Please check the class at Elementor’s developers guide. A detailed description is provided there. We shall do it in steps for better insight.

Create a custom class called “Tartist_Elementor_Extension” and soon after the class, instantiate it and call to run with Tartist_Elementor_Extension::instance();

/**
 * Main Elementor Extension Class
 * The main class that initiates and runs the plugin.
 * @since 1.0.0
 * 
 * The final keyword prevents child classes from overriding a method by prefixing the definition with final. 
 * It means if we define a method with final then it prevents us to override the method.
 */
final class Tartist_Elementor_Extension {
    //code goes here
}

// instantiate the class `Tartist_Elementor_Extension` and run
Tartist_Elementor_Extension::instance();

All of our main functions, constants, elements manager, widgets and controls will be here in this class. As this plugin is intended to extend Elementor, we must check and validate if the main plugin Elementor is installed and activated. Otherwise show some notices. We shall do it now.

Add the following code inside the main class Tartist_Elementor_Extension.

/**
 * Plugin Version
 * @since 1.0.0
 * @var string The plugin version.
 */
const VERSION = '1.0.0';

/**
 * Minimum Elementor Version
 * @since 1.0.0
 * @var string Minimum Elementor version required to run the plugin.
 */
const MINIMUM_ELEMENTOR_VERSION = '2.9.7';

/**
 * Minimum PHP Version
 * @since 1.0.0
 * @var string Minimum PHP version required to run the plugin.
 */
const MINIMUM_PHP_VERSION = '7.0';

/**
 * Instance
 * @since 1.0.0
 * @access private
 * @static
 * @var Tartist_Elementor_Extension The single instance of the class.
 */
private static $_instance = null;

/**
 * Instance
 * Ensures only one instance of the class is loaded or can be loaded.
 * @since 1.0.0
 * @access public
 * @static
 * @return Tartist_Elementor_Extension An instance of the class.
 */
public static function instance() {
    if ( is_null( self::$_instance ) ) {
        self::$_instance = new self();
    }
    return self::$_instance;
}

/**
 * Constructor
 * @since 1.0.0
 * @access public
 */
public function __construct() {
    add_action( 'init', [ $this, 'i18n' ] );
    add_action( 'plugins_loaded', [ $this, 'init' ] );
}

/**
 * Load Textdomain
 * Load plugin localization files.
 * Fired by `init` action hook.
 * @since 1.0.0
 * @access public
 */
public function i18n() {
    load_plugin_textdomain( 'tartist-elementor-extension' );
}

/**
 * Initialize the plugin
 *
 * Load the plugin only after Elementor (and other plugins) are loaded.
 * Checks for basic plugin requirements, if one check fail don't continue,
 * if all check have passed load the files required to run the plugin.
 *
 * Fired by `plugins_loaded` action hook.
 * @since 1.0.0
 * @access public
 */
public function init() {

    // Check if Elementor installed and activated
    if ( ! did_action( 'elementor/loaded' ) ) {
        add_action( 'admin_notices', [ $this, 'admin_notice_missing_main_plugin' ] );
        return;
    }

    // Check for required Elementor version
    if ( ! version_compare( ELEMENTOR_VERSION, self::MINIMUM_ELEMENTOR_VERSION, '>=' ) ) {
        add_action( 'admin_notices', [ $this, 'admin_notice_minimum_elementor_version' ] );
        return;
    }

    // Check for required PHP version
    if ( version_compare( PHP_VERSION, self::MINIMUM_PHP_VERSION, '<' ) ) {
        add_action( 'admin_notices', [ $this, 'admin_notice_minimum_php_version' ] );
        return;
    }

    // 1. Add Plugin actions
    // here we will add actions to elementor widgets and controls

    // 2. Register Widget Styles
    // here we will add action to enqueue styles

    // 3. Register custom categories
    // here we will add actions to create a custom category for our widgets

}

/**
 * Admin notice
 * Warning when the site doesn't have Elementor installed or activated.
 * @since 1.0.0
 * @access public
 */
public function admin_notice_missing_main_plugin() {

    if ( isset( $_GET['activate'] ) ) unset( $_GET['activate'] );

    $message = sprintf(
        /* translators: 1: Plugin name 2: Elementor */
        esc_html__( '"%1$s" requires "%2$s" to be installed and activated.', 'tartist-elementor-extension' ),
        '<strong>' . esc_html__( 'Tartist Elementor Extension', 'tartist-elementor-extension' ) . '</strong>',
        '<strong>' . esc_html__( 'Elementor', 'tartist-elementor-extension' ) . '</strong>'
    );

    printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );

}

/**
 * Admin notice
 * Warning when the site doesn't have a minimum required Elementor version.
 * @since 1.0.0
 * @access public
 */
public function admin_notice_minimum_elementor_version() {

    if ( isset( $_GET['activate'] ) ) unset( $_GET['activate'] );

    $message = sprintf(
        /* translators: 1: Plugin name 2: Elementor 3: Required Elementor version */
        esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'tartist-elementor-extension' ),
        '<strong>' . esc_html__( 'Tartist Elementor Extension', 'tartist-elementor-extension' ) . '</strong>',
        '<strong>' . esc_html__( 'Elementor', 'tartist-elementor-extension' ) . '</strong>',
            self::MINIMUM_ELEMENTOR_VERSION
    );

    printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );

}

/**
 * Admin notice
 * Warning when the site doesn't have a minimum required PHP version.
 * @since 1.0.0
 * @access public
 */
public function admin_notice_minimum_php_version() {

    if ( isset( $_GET['activate'] ) ) unset( $_GET['activate'] );

    $message = sprintf(
        /* translators: 1: Plugin name 2: PHP 3: Required PHP version */
        esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'tartist-elementor-extension' ),
        '<strong>' . esc_html__( 'Tartist Elementor Extension', 'tartist-elementor-extension' ) . '</strong>',
        '<strong>' . esc_html__( 'PHP', 'tartist-elementor-extension' ) . '</strong>',
            self::MINIMUM_PHP_VERSION
    );

    printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );

}

So far, we did nothing fancy but created the following things –

  1. We have created our plugin version constant.
  2. The minimum Elementor version constant check is done.
  3. We also have done minimum PHP version constant.
  4. Then we did the constructor public function __construct().
  5. The main init function public function init() is created, where we will call other methods/functions. This is very important one and we will focus on it frequently from now on.
  6. Lastly, we have created 3 admin notices function which are called via the public function init(). This will check and validate all the constants we have declared to check compatibility.

If you notice, we have created 3 blank areas with comments inside the public function init() which are –

// 1. Add Plugin actions
// here we will add actions to elementor widgets and controls

// 2. Register Widget Styles
// here we will add action to enqueue styles

// 3. Register custom categories
// here we will add actions to create a custom category for our widgets

Presently, the plugin only does the security checks and compatibility checks with Elementor. In my next tutorial (part 2 of this series), I will start creating the widget itself, controls and custom categories.


Other parts of the series

  1. Part 1 – You are reading…
  2. The skeleton of the widget
  3. Create the render template with dynamic content
  4. The controls and final output
  5. Project Files

Leave a Reply