Elementor Widget Taxonomy Update
January 6, 2025 · AI Conversations
To do this, you need to update the way you are setting the `taxonomy` option in the repeater control. Instead of storing the term ID in the `taxonomy` field, you should store the term name. Here's how you can do it:
### Updated Code
Replace the following part in your `_register_controls()` method:
foreach ( $taxonomies as $taxonomy ) {
$taxonomy_options[ $taxonomy->term_id ] = $taxonomy->name;
}
with:
foreach ( $taxonomies as $taxonomy ) {
$taxonomy_options[ $taxonomy->name ] = $taxonomy->name; // Use name as the key
}
Then, in the `render()` method, you can use the taxonomy name directly without looking up the term by ID. Update the render method as follows:
protected function render() {
$settings = $this->get_settings_for_display();
if ( ! empty( $settings['taxonomy_list'] ) ) {
echo '<div class="taxonomy-widget-repeater">';
foreach ( $settings['taxonomy_list'] as $index => $item ) {
$taxonomy = $item['taxonomy']; // Now this is the name
$description = $item['description'];
$image = $item['image']['url'];
$term = get_term_by('name', $taxonomy, 'leistung'); // Get term by name
$term_link = get_term_link($term, 'leistung'); // Link based on term object
echo '<div class="taxonomy-item">';
if ( $term ) {
echo '<p><strong>Selected Taxonomy:</strong> <a href="' . esc_url($term_link) . '">' . esc_html( $term->name ) . '</a></p>';
}
if ( $description ) {
echo '<p><strong>Description:</strong> ' . esc_html( $description ) . '</p>';
}
if ( $image ) {
echo '<p><img src="' . esc_url( $image ) . '" alt="' . esc_attr( $description ) . '" style="max-width: 100%; height: auto;"></p>';
}
echo '</div>';
}
echo '</div>';
}
}
### Key Changes
1. **Use Taxonomy Name as Key**: Update the `taxonomy_options` to use the taxonomy name as the key for the repeater control.
2. **Get Term by Name**: Change the way you retrieve the term in the `render()` method to use `get_term_by('name', $taxonomy, 'leistung')`, which allows you to get the term object based on the name.
With these changes, your widget will correctly display the taxonomy name in the control and the rendered output.
### Update Code
1. **Store Term IDs in the Repeater**: You will store the term IDs in the repeater control, but you'll display the term names in the Elementor interface.
2. **Update the Repeater Control**: Change the options for the repeater control to use the term ID but display the term name.
Here's the modified code:
#### `_register_controls()` Method
Keep storing term IDs, but use term names for display:
protected function _register_controls() {
$taxonomies = get_terms([
'taxonomy' => 'leistung',
'orderby' => 'name',
'hide_empty'=>false
]);
$taxonomy_options = [];
foreach ( $taxonomies as $taxonomy ) {
$taxonomy_options[ $taxonomy->term_id ] = $taxonomy->name; // Store term ID as key and name as value
}
// Repeater control
$repeater = new ElementorRepeater();
$repeater->add_control(
'taxonomy',
[
'label' => __( 'Select Leistungen', 'solaron' ),
'type' => ElementorControls_Manager::SELECT,
'options' => $taxonomy_options,
]
);
$repeater->add_control(
'description',
[
'label' => __( 'Description', 'solaron' ),
'type' => ElementorControls_Manager::TEXTAREA,
'placeholder' => __( 'Enter description here...', 'solaron' ),
]
);
$repeater->add_control(
'image',
[
'label' => __( 'Upload Image', 'solaron' ),
'type' => ElementorControls_Manager::MEDIA,
'default' => [
'url' => ElementorUtils::get_placeholder_image_src(),
],
]
);
$this->start_controls_section(
'content_section',
[
'label' => __( 'Content', 'solaron' ),
'tab' => ElementorControls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'taxonomy_list',
[
'label' => __( 'Taxonomy Items', 'solaron' ),
'type' => ElementorControls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
'title_field' => '{{{ taxonomy }}} - {{{ description }}}',
]
);
$this->end_controls_section();
}
#### `render()` Method
In the `render()` method, when you want to retrieve the term data, you can continue to use the term ID saved in the repeater:
protected function render() {
$settings = $this->get_settings_for_display();
if ( ! empty( $settings['taxonomy_list'] ) ) {
echo '<div class="taxonomy-widget-repeater">';
foreach ( $settings['taxonomy_list'] as $index => $item ) {
$taxonomy_id = $item['taxonomy']; // This is the term ID
$description = $item['description'];
$image = $item['image']['url'];
$term = get_term( $taxonomy_id, 'leistung' ); // Get term by ID
$term_link = get_term_link( $term, 'leistung' ); // Link based on term object
echo '<div class="taxonomy-item">';
if ( $term && ! is_wp_error( $term ) ) {
echo '<p><strong>Selected Taxonomy:</strong> <a href="' . esc_url($term_link) . '">' . esc_html( $term->name ) . '</a></p>';
}
if ( $description ) {
echo '<p><strong>Description:</strong> ' . esc_html( $description ) . '</p>';
}
if ( $image ) {
echo '<p><img src="' . esc_url( $image ) . '" alt="' . esc_attr( $description ) . '" style="max-width: 100%; height: auto;"></p>';
}
echo '</div>';
}
echo '</div>';
}
}
### Key Changes
– **Store Term ID**: The `taxonomy` field in the repeater control still stores the term ID as the value.
– **Display Term Name**: In the `render()` method, use `get_term()` to retrieve the term object based on the stored term ID, allowing you to display the term name and link correctly.
With these changes, you'll save the term ID in the database while still displaying the term names in the Elementor widget interface.
Instead, you can implement a custom validation check in the `render()` method to ensure the user selects a taxonomy before rendering the widget. If no taxonomy is selected, you can display an error message.
Here's how you can do it:
### Step 1: Update the Repeater Control
Add a label indicating that the field is required. This is more of a user interface hint since Elementor doesn't enforce this validation automatically:
$repeater->add_control(
'taxonomy',
[
'label' => __( 'Select Leistungen (required)', 'solaron' ),
'type' => ElementorControls_Manager::SELECT,
'options' => $taxonomy_options,
'default' => '', // Set default to empty
]
);
### Step 2: Add Validation in the Render Method
In the `render()` method, check if a taxonomy is selected and display an error message if not:
protected function render() {
$settings = $this->get_settings_for_display();
// Check if taxonomy list is not empty
if ( ! empty( $settings['taxonomy_list'] ) ) {
echo '<div class="taxonomy-widget-repeater">';
foreach ( $settings['taxonomy_list'] as $index => $item ) {
$taxonomy_id = $item['taxonomy']; // This is the term ID
$description = $item['description'];
$image = $item['image']['url'];
// Check if a taxonomy is selected
if ( empty( $taxonomy_id ) ) {
echo '<p style="color: red;">' . __( 'Please select a taxonomy.', 'solaron' ) . '</p>';
continue; // Skip rendering this item
}
$term = get_term( $taxonomy_id, 'leistung' ); // Get term by ID
$term_link = get_term_link( $term, 'leistung' ); // Link based on term object
echo '<div class="taxonomy-item">';
if ( $term && ! is_wp_error( $term ) ) {
echo '<p><strong>Selected Taxonomy:</strong> <a href="' . esc_url($term_link) . '">' . esc_html( $term->name ) . '</a></p>';
}
if ( $description ) {
echo '<p><strong>Description:</strong> ' . esc_html( $description ) . '</p>';
}
if ( $image ) {
echo '<p><img src="' . esc_url( $image ) . '" alt="' . esc_attr( $description ) . '" style="max-width: 100%; height: auto;"></p>';
}
echo '</div>';
}
echo '</div>';
} else {
echo '<p style="color: red;">' . __( 'No taxonomy items found. Please add some in the widget settings.', 'solaron' ) . '</p>';
}
}
### Explanation of Changes
1. **Label for Required Field**: Update the dropdown label to indicate that it is a required field.
2. **Validation Check**: In the `render()` method, check if the `taxonomy_id` is empty. If it is, display a red error message and skip rendering that item.
3. **Error Handling**: If no taxonomy items are found, display a message indicating that the user should add some in the widget settings.
### Note
While this approach provides user feedback, it's essential to note that this method does not enforce the required field at the Elementor editor level; users could still save the widget without selecting a taxonomy. For more robust validation, consider extending Elementor's controls or adding custom JavaScript to enforce required fields in the editor interface.