Elementor Widget Post Settings
December 31, 2024 · AI Conversations
### Steps:
1. **Locate Your Custom Widget Class**
If you've already created a custom Elementor widget, open its PHP file.
2. **Add Controls for Number of Posts and Order By**
Use the `add_control` method to include these options in your widget.
Here’s a sample code snippet:
protected function _register_controls() {
$this->start_controls_section(
'content_section',
[
'label' => __( 'Content', 'your-text-domain' ),
'tab' => ElementorControls_Manager::TAB_CONTENT,
]
);
// Number of Posts Control
$this->add_control(
'number_of_posts',
[
'label' => __( 'Number of Posts', 'your-text-domain' ),
'type' => ElementorControls_Manager::NUMBER,
'default' => 5,
'description' => __( 'Enter the number of posts to display.', 'your-text-domain' ),
]
);
// Order By Control
$this->add_control(
'order_by',
[
'label' => __( 'Order By', 'your-text-domain' ),
'type' => ElementorControls_Manager::SELECT,
'default' => 'date',
'options' => [
'date' => __( 'Date', 'your-text-domain' ),
'title' => __( 'Title', 'your-text-domain' ),
'rand' => __( 'Random', 'your-text-domain' ),
'ID' => __( 'ID', 'your-text-domain' ),
],
'description' => __( 'Select the order for displaying posts.', 'your-text-domain' ),
]
);
$this->end_controls_section();
}
3. **Fetch Posts in the Widget Render Method**
Use these settings to query posts in the `render()` method.
protected function render() {
$settings = $this->get_settings_for_display();
$args = [
'post_type' => 'post',
'posts_per_page' => $settings['number_of_posts'],
'orderby' => $settings['order_by'],
];
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<div class="custom-posts-list">';
while ($query->have_posts()) {
$query->the_post();
echo '<div class="post-item">';
echo '<h2><a href="' . get_permalink() . '">' . get_the_title() . '</a></h2>';
echo '</div>';
}
echo '</div>';
}
wp_reset_postdata();
}
4. **Test the Widget**
– Add the widget in Elementor and verify that the fields appear in the settings panel.
– Ensure the "Number of Posts" and "Order By" options work as expected.
5. **Optional Enhancements**
– Add a control for selecting post types if you want to extend functionality.
– Include validation for input fields if needed.
Let me know if you need help with testing or enhancing this!
### Updated Code:
protected function _register_controls() {
$this->start_controls_section(
'content_section',
[
'label' => __( 'Content', 'your-text-domain' ),
'tab' => ElementorControls_Manager::TAB_CONTENT,
]
);
// Number of Posts Control
$this->add_control(
'number_of_posts',
[
'label' => __( 'Number of Posts', 'your-text-domain' ),
'type' => ElementorControls_Manager::NUMBER,
'default' => 2, // Default number of posts
'description' => __( 'Enter the number of posts to display.', 'your-text-domain' ),
]
);
// Order By Control
$this->add_control(
'order_by',
[
'label' => __( 'Order By', 'your-text-domain' ),
'type' => ElementorControls_Manager::SELECT,
'default' => 'date', // Default ordering
'options' => [
'date' => __( 'Date', 'your-text-domain' ),
'title' => __( 'Title', 'your-text-domain' ),
'rand' => __( 'Random', 'your-text-domain' ),
'ID' => __( 'ID', 'your-text-domain' ),
],
'description' => __( 'Select the field to order posts by.', 'your-text-domain' ),
]
);
// Order Control (Ascending/Descending)
$this->add_control(
'order',
[
'label' => __( 'Order', 'your-text-domain' ),
'type' => ElementorControls_Manager::SELECT,
'default' => 'DESC', // Default order
'options' => [
'ASC' => __( 'Ascending', 'your-text-domain' ),
'DESC' => __( 'Descending', 'your-text-domain' ),
],
'description' => __( 'Select the order direction.', 'your-text-domain' ),
]
);
$this->end_controls_section();
}
### Update the `render()` Method
Adjust the `render()` method to incorporate the new `order` option:
protected function render() {
$settings = $this->get_settings_for_display();
$args = [
'post_type' => 'post',
'posts_per_page' => $settings['number_of_posts'], // Number of posts to display
'orderby' => $settings['order_by'], // Field to order by
'order' => $settings['order'], // ASC or DESC
];
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<div class="custom-posts-list">';
while ($query->have_posts()) {
$query->the_post();
echo '<div class="post-item">';
echo '<h2><a href="' . get_permalink() . '">' . get_the_title() . '</a></h2>';
echo '</div>';
}
echo '</div>';
}
wp_reset_postdata();
}
### Summary of Changes:
1. **Default Values:**
– `number_of_posts`: Default is set to `2`.
– `order_by`: Default is set to `date`.
– `order`: Default is set to `DESC`.
2. **New Control:**
– `order`: Added to allow "Ascending" or "Descending" order.
3. **Query Adjustments:**
– The query now includes the `order` parameter.
### Testing:
– Add your widget to a page in Elementor.
– Adjust the "Number of Posts," "Order By," and "Order" settings to test different configurations.
Let me know if you need additional functionality!
Here’s the updated `render()` method with the validation:
### Updated `render()` Method:
protected function render() {
$settings = $this->get_settings_for_display();
// Validate number of posts
$number_of_posts = isset($settings['number_of_posts']) && is_numeric($settings['number_of_posts']) && $settings['number_of_posts'] > 0
? intval($settings['number_of_posts'])
: 3; // Default to 3 if validation fails
$args = [
'post_type' => 'post',
'posts_per_page' => $number_of_posts, // Number of posts to display
'orderby' => $settings['order_by'] ?? 'date', // Default to 'date' if not set
'order' => $settings['order'] ?? 'DESC', // Default to 'DESC' if not set
];
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<div class="custom-posts-list">';
while ($query->have_posts()) {
$query->the_post();
echo '<div class="post-item">';
echo '<h2><a href="' . get_permalink() . '">' . get_the_title() . '</a></h2>';
echo '</div>';
}
echo '</div>';
}
wp_reset_postdata();
}
### Explanation of Changes:
1. **Validation for `number_of_posts`:**
– Checks if the field exists, is numeric, and greater than 0.
– Defaults to `3` if validation fails.
2. **Fallback for `order_by` and `order`:**
– `order_by`: Defaults to `'date'` if not set.
– `order`: Defaults to `'DESC'` if not set.
### Summary:
– If the user enters an invalid value for the "Number of Posts" field (e.g., negative numbers, non-numeric values), the widget will gracefully fall back to displaying 3 posts.
– The `order_by` and `order` fields also have default values to prevent errors.
This approach ensures that your widget is robust and handles invalid user input correctly. Let me know if you need further assistance!
$('.project-taxonomy-filter').on('change', function () {
let filters = {};
// Loop through all dropdowns to collect data
$('.project-taxonomy-filter').each(function () {
const taxonomy = $(this).data('taxonomy');
const slug = $(this).val();
if (slug) {
filters[taxonomy] = slug;
}
});
$.ajax({
url: solaron_ajax.ajax_url,
type: 'POST',
data: {
action: 'filter_project_posts',
filters: filters,
},
beforeSend: function () {
$('#ajax-project-content').html('Loading…');
},
success: function (response) {
$('#ajax-project-content').html(response);
},
});
});
});
apply above if project-taxonomy-filter class exist on that page
### Updated Script:
jQuery(document).ready(function ($) {
// Check if elements with the class 'project-taxonomy-filter' exist
if ($('.project-taxonomy-filter').length > 0) {
$('.project-taxonomy-filter').on('change', function () {
let filters = {};
// Loop through all dropdowns to collect data
$('.project-taxonomy-filter').each(function () {
const taxonomy = $(this).data('taxonomy');
const slug = $(this).val();
if (slug) {
filters[taxonomy] = slug;
}
});
$.ajax({
url: solaron_ajax.ajax_url,
type: 'POST',
data: {
action: 'filter_project_posts',
filters: filters,
},
beforeSend: function () {
$('#ajax-project-content').html('<p>Loading...</p>');
},
success: function (response) {
$('#ajax-project-content').html(response);
},
});
});
}
});
### Explanation of Changes:
1. **Existence Check:**
Before binding the event handler, the script checks if any elements with the `.project-taxonomy-filter` class exist using `if ($('.project-taxonomy-filter').length > 0)`.
2. **Prevents Unnecessary Binding:**
If the class is not present, the script does nothing, improving performance and avoiding errors.
### Additional Notes:
– Ensure that the `solaron_ajax.ajax_url` variable is correctly localized in your WordPress setup using `wp_localize_script`.
– Verify that the `#ajax-project-content` element is present on the page where you expect the content to be updated.
This approach ensures the script runs only when the required elements are present on the page. Let me know if you need further adjustments!