Elementor Widget Taxonomy Update

User
Assistant
It looks like you want to modify the `taxonomy_list` control in your Elementor widget to display the taxonomy name instead of its ID when the widget is rendered. The current implementation uses the term ID for the `taxonomy` field, but you want to show the term name.

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.

User
but i want to save term id in db
Assistant
If you want to save the term ID in the database while displaying the taxonomy name in the Elementor control, you can achieve this by slightly modifying your implementation. Here’s how you can do it:

### 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.

User
give dropdown required field
Assistant
To make the dropdown field for selecting a taxonomy required in your Elementor widget, you can use the `required` attribute in the control definition. However, Elementor does not natively support a `required` attribute directly in the control settings.

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.

Leave a Comment

Your email address will not be published. Required fields are marked *