Skip to content

Instantly share code, notes, and snippets.

@prantomollick
Last active January 19, 2025 14:59
Show Gist options
  • Save prantomollick/96496d3fbbee8ee2170f8656605a1a95 to your computer and use it in GitHub Desktop.
Save prantomollick/96496d3fbbee8ee2170f8656605a1a95 to your computer and use it in GitHub Desktop.
elementor-blog-post-widget | Blog Post Queries Based on Terms (categories) | Blog Post query in WordPress
<?php
namespace Aidzone_Core\Widgets;
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Elementor Hello World
*
* Elementor widget for hello world.
*
* @since 1.0.0
*/
class Aidzone_Blog_Post extends Widget_Base {
/**
* Retrieve the widget name.
*
* @since 1.0.0
*
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'aidzone-blog-post';
}
/**
* Retrieve the widget title.
*
* @since 1.0.0
*
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Aidzone Blog Post', 'aidzone-core' );
}
/**
* Retrieve the widget icon.
*
* @since 1.0.0
*
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-post-list';
}
/**
* Retrieve the list of categories the widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* Note that currently Elementor supports only one category.
* When multiple categories passed, Elementor uses the first one.
*
* @since 1.0.0
*
* @access public
*
* @return array Widget categories.
*/
public function get_categories() {
return [ 'aidzone-widget-category' ];
}
/**
* Retrieve the list of scripts the widget depended on.
*
* Used to set scripts dependencies required to run the widget.
*
* @since 1.0.0
*
* @access public
*
* @return array Widget scripts dependencies.
*/
public function get_script_depends() {
return [ 'aidzone-core' ];
}
/**
* Register the widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 1.0.0
*
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'aidzone_post_section',
[
'label' => __( 'Blog Post', 'aidzone-core' ),
]
);
$this->add_control(
'post_per_page',
[
'label' => __( 'Post Per Page', 'aidzone-core' ),
'type' => Controls_Manager::NUMBER,
'default' => 3,
]
);
$this->add_control(
'cat_include',
[
'label' => __( 'Include Category', 'aidzone-core' ),
'type' => Controls_Manager::SELECT2,
'label_block' => true,
'multiple' => true,
'options' => aidzone_get_categories(),
]
);
$this->add_control(
'cat_exclude',
[
'label' => __( 'Exclude Category', 'aidzone-core' ),
'type' => Controls_Manager::SELECT2,
'label_block' => true,
'multiple' => true,
'options' => aidzone_get_categories()
]
);
$this->add_control(
'post_include',
[
'label' => __( 'Include Post', 'aidzone-core' ),
'type' => Controls_Manager::SELECT2,
'label_block' => true,
'multiple' => true,
'options' => aidzone_get_posts(),
]
);
$this->add_control(
'post_exclude',
[
'label' => __( 'Exclude Post', 'aidzone-core' ),
'type' => Controls_Manager::SELECT2,
'label_block' => true,
'multiple' => true,
'options' => aidzone_get_posts(),
]
);
$this->add_control(
'post_order',
[
'label' => __( 'Order', 'aidzone-core' ),
'type' => Controls_Manager::SELECT,
'options' => [
'ASC' => __( 'Ascending', 'aidzone-core' ),
'DESC' => __( 'Descending', 'aidzone-core' ),
],
'default' => 'DESC',
]
);
$this->add_control(
'post_orderby',
[
'label' => __( 'Order By', 'aidzone-core' ),
'type' => Controls_Manager::SELECT,
'options' => [
'ID' => __( 'Post ID', 'aidzone-core' ),
'author' => __( 'Author', 'aidzone-core' ),
'title' => __( 'Title', 'aidzone-core' ),
'date' => __( 'Date', 'aidzone-core' ),
'modified' => __( 'Last Modified Date', 'aidzone-core' ),
'parent' => __( 'Parent ID', 'aidzone-core' ),
'rand' => __( 'Random', 'aidzone-core' ),
'comment_count' => __( 'Comment Count', 'aidzone-core' ),
'menu_order' => __( 'Menu Order', 'aidzone-core' ),
],
'default' => 'date',
]
);
$this->end_controls_section();
// Style control
$this->start_controls_section(
'section_style',
[
'label' => __( 'Style', 'aidzone-core' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'heading_color',
[
'label' => esc_html__( 'Heading Color', 'aidzone-core' ),
'type' => Controls_Manager::COLOR,
'default' => '#f00',
'selectors' => [
'{{WRAPPER}} .tp-section-title' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'text_transform',
[
'label' => __( 'Text Transform', 'aidzone-core' ),
'type' => Controls_Manager::SELECT,
'default' => '',
'options' => [
'' => __( 'None', 'aidzone-core' ),
'uppercase' => __( 'UPPERCASE', 'aidzone-core' ),
'lowercase' => __( 'lowercase', 'aidzone-core' ),
'capitalize' => __( 'Capitalize', 'aidzone-core' ),
],
'selectors' => [
'{{WRAPPER}} .tp-section-title' => 'text-transform: {{VALUE}};',
],
]
);
$this->end_controls_section();
}
/**
* Render the widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
*
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$args = [
'post_type' => 'post',
'posts_per_page' => $settings['post_per_page'],
'orderby' => $settings['post_orderby'],
'order' => $settings['post_order'],
'post__in' => $settings['post_include'],
'post__not_in' => $settings['post_exclude']
];
if(!empty($settings['cat_include']) and !empty($settings['cat_exclude'])) {
$args['tax_query'] = [
'relation' => 'AND',
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $settings['cat_include'],
'operator' => 'IN'
],
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $settings['cat_exclude'],
'operator' => 'NOT IN'
]
];
} elseif ( !empty($settings['cat_include']) || !empty($settings['cat_exclude']) ) {
$args['tax_query'] = [
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => !empty($settings['cat_include']) ? $settings['cat_include'] : $settings['cat_exclude'],
'operator' => !empty($settings['cat_include']) ? 'IN' : 'NOT IN'
]
];
}
$query = new \WP_Query($args);
?>
<section class="tp-blog-area tp-plr-rs pt-100 pb-180">
<div class="container">
<div class="row xl-flex-row-gap-70">
<?php
if( $query->have_posts() ) :
while( $query->have_posts() ) :
$query->the_post();
$categories = get_the_category(get_the_ID());
// echo '<pre>';
// print_r($categories);
// echo '</pre>';
?>
<div class="col-xl-4 col-lg-6 col-md-6">
<div class="tp-blog-item wow tpfadeUp" data-wow-duration=".9s" data-wow-delay=".5s">
<a href="<?php the_permalink(); ?>">
<div class="tp-blog-thumb">
<?php the_post_thumbnail(); ?>
</div>
<span class="tp-blog-categories"><?php echo esc_html($categories[0]->name)?></span>
<div class="tp-blog-dsc">
<h3 class="tp-blog-title tp-title-hover"><?php the_title(); ?></h3>
</div>
<div class="tp-blog-meta d-flex align-items-center justify-content-between">
<div class="tp-blog-meta-date">
<span><?php echo get_the_date(); ?></span>
</div>
<div class="tp-blog-meta-action">
<span>READ MORE</span>
</div>
</div>
</a>
</div>
</div>
<?php endwhile; wp_reset_postdata(); endif; ?>
</div>
</div>
</section>
<?php
}
}
$widgets_manager->register( new Aidzone_Blog_Post() );
<?php
/**
* Retrieves a list of categories or custom taxonomy terms.
*
* @param string $taxonomy Taxonomy name. Default is 'category'.
* @return array Associative array of term slugs and names.
*/
function aidzone_get_categories($taxonomy = 'category') {
// Get all terms for the specified taxonomy
$terms = get_categories([
'taxonomy' => $taxonomy,
'orderby' => 'name',
'order' => 'ASC',
]);
// Check for errors or empty result
if (is_wp_error($terms) || empty($terms)) {
return [];
}
// Build an associative array of term slugs and names
$categories = [];
foreach ($terms as $term) {
$categories[$term->slug] = $term->name;
}
return $categories;
}
/**
* Retrieves a list of posts for a specified post type.
*
* @param string $post_type_name Post type name. Default is 'post'.
* @return array Associative array of post IDs and titles.
*/
function aidzone_get_posts($post_type_name = 'post') {
// Fetch all posts for the specified post type, ordered by title in ascending order
$posts = get_posts( [
'post_type' => $post_type_name,
'orderby' => 'title',
'order' => 'ASC',
]);
// Check if there was an error fetching posts or if the result is empty
if (is_wp_error($posts) || empty($posts)) {
return [];
}
// Initialize an associative array to hold post IDs and titles
$post_list = [];
// Iterate over the fetched posts to populate the associative array
foreach ($posts as $post) {
$post_list[$post->ID] = $post->post_title;
}
// Return the associative array of post IDs and titles
return $post_list;
}
@prantomollick
Copy link
Author

Elementor Blog Post Widget

This repository contains a custom Elementor widget for displaying blog posts. It provides options to filter posts by category, specific post IDs, and control the order and number of posts displayed. The widget also includes styling options for the heading.

Features

  • Flexible Filtering: Display posts based on included/excluded categories and specific post IDs.
  • Ordering and Limiting: Control the order (ascending/descending) and the number of posts displayed.
  • Styling Options: Customize the heading color and text transform.
  • Easy Integration: Seamlessly integrates with Elementor.

Installation

  1. Download/Clone: Download or clone this repository to your WordPress wp-content/plugins directory.
  2. Activate Plugin: Activate the plugin through the 'Plugins' menu in WordPress. (You might need to create a plugin file containing the code or zip it as a plugin to be able to activate it)
  3. Use in Elementor: The "Aidzone Blog Post" widget will now be available in the Elementor editor.

Widget Options

The widget provides the following options in the Elementor editor:

  • Post Per Page: Number of posts to display.
  • Include Category: Select categories to include posts from.
  • Exclude Category: Select categories to exclude posts from.
  • Include Post: Select specific posts to include by ID.
  • Exclude Post: Select specific posts to exclude by ID.
  • Order: Ascending or descending order of posts.
  • Order By: Order posts by ID, author, title, date, etc.
  • Heading Color: Set the color of the heading.
  • Text Transform: Apply text transform (uppercase, lowercase, capitalize) to the heading.

Helper Functions (in core-functions.php)

This widget relies on the following helper functions:

  • aidzone_get_categories($taxonomy = 'category'): Retrieves an associative array of term slugs and names for a given taxonomy (defaults to 'category'). Useful for populating the category selection controls in the widget.

  • aidzone_get_posts($post_type_name = 'post'): Retrieves an associative array of post IDs and titles for a given post type (defaults to 'post'). Useful for populating the post selection controls in the widget.

Example Usage

// Assuming this code is part of an Elementor widget class.
$settings = $this->get_settings_for_display();

$args = [
    // ... (see blog-post.php for query arguments)
];

$query = new \WP_Query($args);

if ($query->have_posts()) :
    while ($query->have_posts()) : $query->the_post();
        // Display post content here...
    endwhile;
    wp_reset_postdata();
endif;

@prantomollick
Copy link
Author

Elementor Blog Post Widget

This repository contains a custom Elementor widget for displaying blog posts. It provides options to filter posts by category, specific post IDs, and control the order and number of posts displayed. The widget also includes styling options for the heading.

Features

  • Flexible Filtering: Display posts based on included/excluded categories and specific post IDs.
  • Ordering and Limiting: Control the order (ascending/descending) and the number of posts displayed.
  • Styling Options: Customize the heading color and text transform.
  • Easy Integration: Seamlessly integrates with Elementor.

Installation

  1. Download/Clone: Download or clone this repository to your WordPress wp-content/plugins directory.
  2. Activate Plugin: Activate the plugin through the 'Plugins' menu in WordPress. (You might need to create a plugin file containing the code or zip it as a plugin to be able to activate it)
  3. Use in Elementor: The "Aidzone Blog Post" widget will now be available in the Elementor editor.

Widget Options

The widget provides the following options in the Elementor editor:

  • Post Per Page: Number of posts to display.
  • Include Category: Select categories to include posts from.
  • Exclude Category: Select categories to exclude posts from.
  • Include Post: Select specific posts to include by ID.
  • Exclude Post: Select specific posts to exclude by ID.
  • Order: Ascending or descending order of posts.
  • Order By: Order posts by ID, author, title, date, etc.
  • Heading Color: Set the color of the heading.
  • Text Transform: Apply text transform (uppercase, lowercase, capitalize) to the heading.

Helper Functions (in core-functions.php)

This widget relies on the following helper functions:

  • aidzone_get_categories($taxonomy = 'category'): Retrieves an associative array of term slugs and names for a given taxonomy (defaults to 'category'). Useful for populating the category selection controls in the widget.

  • aidzone_get_posts($post_type_name = 'post'): Retrieves an associative array of post IDs and titles for a given post type (defaults to 'post'). Useful for populating the post selection controls in the widget.

Example Usage

// Assuming this code is part of an Elementor widget class.
$settings = $this->get_settings_for_display();

$args = [
    // ... (see blog-post.php for query arguments)
];

$query = new \WP_Query($args);

if ($query->have_posts()) :
    while ($query->have_posts()) : $query->the_post();
        // Display post content here...
    endwhile;
    wp_reset_postdata();
endif;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment