Hook for modyfying widget content
-
Hello,
I am new with WP development and trying to create WP plugin.
The thing I need to do is to add a html tag buttons for default text widget with ready made html templates when the user press the button. I already got the buttons, but what I can’t figure out what filter/action(or none of them) should I use to make that html template (for example <div></div>) to appear into wordpress text widget’s content text field?
Thanks in advance!
Regards,
Darius
-
Use wp_register_sidebar_widget() to register a variant of the text widget. Use the
$params
argument to passarray('before_widget'=>'your html here',)
Users can then add this variant to their theme’s sidebar and your HTML will appear before any text they enter.
You can also inject this param by using the ‘dynamic_sidebar_params’ filter.
Thanks for response!
I created similar widget like default by extending default wp class WP_Widget().
And inside form function I wrote this:
function form($instance) {
// Check values
if( $instance) {
$title = esc_attr($instance[‘title’]);
$textarea = esc_textarea($instance[‘textarea’]);
} else {
$title = ”;
$textarea = ”;
}
?>
<p>
<label for=”<?php echo $this->get_field_id(‘title’); ?>”><?php _e(‘Widget Title’, ‘wp_widget_plugin’); ?></label>
<input class=”widefat” id=”<?php echo $this->get_field_id(‘title’); ?>” name=”<?php echo $this->get_field_name(‘title’); ?>” type=”text” value=”<?php echo $title; ?>” />
</p>
<p>
<label for=”<?php echo $this->get_field_id(‘textarea’); ?>”><?php _e(‘Textarea:’, ‘wp_widget_plugin’); ?></label>
<textarea class=”widefat” id=”<?php echo $this->get_field_id(‘textarea’); ?>” name=”<?php echo $this->get_field_name(‘textarea’); ?>”><?php echo $textarea; ?></textarea>
</p>
<p>
<button type=”button” onclick=”<?php echo $textarea='<div></div>’; ?>” >div</button>
</p>
<?php
}The problem is my button doesn’t add html tag into textarea in this line:
<button type=”button” onclick=”<?php echo $textarea='<div></div>’; ?>” >div</button>Link to my widget picture:widget picture</>
But if I put it here it works, but withotu button hovewer
<p>
<label for=”<?php echo $this->get_field_id(‘textarea’); ?>”><?php _e(‘Textarea:’, ‘wp_widget_plugin’); ?></label>
<textarea class=”widefat” id=”<?php echo $this->get_field_id(‘textarea’); ?>” name=”<?php echo $this->get_field_name(‘textarea’); ?>”><?php echo $textarea=”<div></div>; ?></textarea>
</p>OK, I think I see your problem now. I was focused on widgets, while your problem is more fundamental, apologies for not getting this sooner.
The onclick attribute for the button HTML needs to be javascript code of some sort. Most times it’s a function call to some more elaborate code, but direct code or closures will work too. I can’t code javascript on the fly like I do with PHP, but to set a value in a text area, your javascript needs to get the textarea object – usually by ID, then assign a value to one of the object properties – object.value or object.innerHtml or, heck, I don’t know, something like that anyway.
The important point is to be sure you separate in your mind what happens on your server with PHP and what happens on the client browser with javascript (or jQuery). Even though PHP and HTML and javascript are mixed up on the code page, the two languages execute at very different, specific times and locations.
I googled and actually got the button to execute php function(the button responds and pops me alert with echo in php), but how do I share variable $textarea to actually make $textarea=”<div></div>” since now it does nothing and I think because those variables inside the WP_widget extends class are local. Only my button are inside this class.
<script> function addHTML(){ alert('<?php addhtmltag(); ?>'); } </script> <?php function addhtmltag() { echo $textarea="<div></div>"; } <button type="button" onclick="addHTML()">div</button>
The preferred way is to use wp_localize_script(). You could do a hacky shortcut for brief snippets by just outputting the value using PHP inside a
<script>
block assignment:<script> var myValue = "<?php echo $my_value ?>"; <\script>
You will find
wp_localize_script()
essentially does the same thing, but it does so in a safe manner that is much more likely to work properly.I am stuck, I tried several approaches, but nothing seems to work, to make that button append the text when I click to the textarea of the wirget.
This is code I got.
<script> function addHTML_div(){ $(document).ready(function(){ $("#add").click(function(){ $('#txtarea').html('test'); }); }); } </script> <script> function addHTML_b(){ alert('<?php addhtmltag_b(); ?>'); } </script> <?php function addhtmltag_div() { echo $textarea="<div></div>"; } function addhtmltag_b() { echo $textarea="<b></b>"; } class wp_my_plugin extends WP_Widget { // constructor function wp_my_plugin() { parent::WP_Widget(false, $name = __('My Widget', 'wp_widget_plugin') ); } // widget form creation function form($instance) { // Check values if( $instance) { $title = esc_attr($instance['title']); $textarea = esc_textarea($instance['textarea']); } else { $title = ''; $textarea = ''; } ?> <p> <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Widget Title', 'wp_widget_plugin'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /> </p> <p> <label for="<?php echo $this->get_field_id('textarea'); ?>"><?php _e('Textarea:', 'wp_widget_plugin'); ?></label> <textarea class="widefat" id="<?php echo $this->get_field_id('textarea'); ?>" name="<?php echo $this->get_field_name('textarea'); ?>"><?php echo $textarea; ?></textarea> </p> <p> <textarea id="txtarea"></textarea> <input type="button" id="add" value="div"></button> <button type="button" onclick="addHTML_b()">b</button> </p> <?php } // widget update function update($new_instance, $old_instance) { $instance = $old_instance; // Fields $instance['title'] = strip_tags($new_instance['title']); $instance['textarea'] = strip_tags($new_instance['textarea']); return $instance; } // widget display function widget($args, $instance) { extract( $args ); // these are the widget options $title = apply_filters('widget_title', $instance['title']); $textarea = $instance['textarea']; echo $before_widget; // Display the widget echo '<div class="widget-text wp_widget_plugin_box">'; // Check if title is set if ( $title ) { echo $before_title . $title . $after_title; } // Check if textarea is set if( $textarea ) { echo '<p class="wp_widget_plugin_textarea">'.$textarea.'</p>'; } echo '</div>'; echo $after_widget; } }
Picture of widget.
Maybe you need to enqueue jQuery? Function Reference/wp enqueue script
The good thing about using
wp_enqueue_script()
is if it is enqueued multiple times on the same page by different scripts, it is still only loaded one time by WP. But it does need to be enqueued at least once!If you’ve done that, I’m unsure of the problem. Check your browser’s console for JS errors for more clues.
Finally I got the button doing what it should do.
I enqueued the jquery you advised
PHP in plugin file:
function dm_enqueue_scripts() { wp_enqueue_script('dm', '/wp-content/plugins/...', null, null, true); } add_action('admin_enqueue_scripts', 'dm_enqueue_scripts');
HTML in plugin file:
<input type="button" class="press_b" value="b" /> <textarea class="addhtml" id="<?php echo $this->get_field_id('textarea'); ?>" name="<?php echo $this->get_field_name('textarea'); ?>"><?php echo $textarea[textarea]; ?></textarea>
JQuery in external file:
jQuery(function($){ $(document).on('click', 'input.press_b', function(evt){ $('.addhtml').val($('.addhtml').val()+'<b></b>'); return false; }); });
Although I have some issues with widget not saving the <b></b> value.
Finally I got the button doing what it should do.
I enqueued the jquery as you advised and the worked out that if I choose to call to html elements by ID it doesn’t work, but by class it works for some reason. Anyway I don’t know javascript/jquery so it might be the nature of language I dunno.
PHP in plugin file:
function dm_enqueue_scripts() { wp_enqueue_script('dm', '/wp-content/plugins/...', null, null, true); } add_action('admin_enqueue_scripts', 'dm_enqueue_scripts');
HTML in plugin file:
<input type="button" class="press_b" value="b" /> <textarea class="addhtml" id="<?php echo $this->get_field_id('textarea'); ?>" name="<?php echo $this->get_field_name('textarea'); ?>"><?php echo $textarea[textarea]; ?></textarea>
JQuery in external file:
jQuery(function($){ $(document).on('click', 'input.press_b', function(evt){ $('.addhtml').val($('.addhtml').val()+'<b></b>'); return false; }); });
Although I have some issues with widget not saving the <b></b> value.
That’s good news, progress!
Though I’m a bit surprised your code works, I think it is due to a happy coincidence. To be sure it continues to work, when you enqueue your script the 3rd parameter should be
array('jquery')
to let WordPress know your script needs jQuery to work.ID selection should work, perhaps you introduced a syntax error in trying to use it? If class works then maybe it should be left alone ??
If the widget value is not being saved I’m guessing there is a problem with your widget class’
update()
method. checking… Ah! Yes, you are usingstrip_tags()
on the textarea value, which strips all HTML tags, even<b></b>
.Thanks ??
What do you mean by “using strip_tags()”? Not saving because of that?
The text I write myself into texarea is saved, but the text I add with the button <div></div> is not. I am assuming maybe it because the jquery script doesn’t send the value back to php?
Okay ye I got it
I promise this is last question ??
Lets imagine scenario:
I press div button 2 times. It adds this to the textarea.
<div></div><div></div>
Then I write some additional text with keyboard.
<div></div><div></div>sadada
Then I press div button again and my typed text dissapears. Textarea value becomes like this. It replaces my sadada text. Ok I didn’t pressed save button maybe thats because of that I am thinking.
<div></div><div></div><div></div>
Now I add some additional text again hit save and press div button again, boom my text is replaced again.
And what is most interestign to me that if after I hit save I refresh the page everything is added fine.
<div></div><div></div>sadada<div></div>
Thank you very much!
My code.
var div = '<div> </div>'; $(document).on('click', 'input.press_div', function(evt){ if(textarea.textarea=='') { textarea.textarea = div; $('.addhtml').val(textarea.textarea); } else { textarea.textarea=textarea.textarea + div; $('.addhtml').val(textarea.textarea); } return false; });
- The topic ‘Hook for modyfying widget content’ is closed to new replies.