Je suis nouveau dans le développement de plugins WordPress et je viens de commencer à travailler avec le widget. Ma question est: Quelles sont les limites de WordPress Widget?
J'ai essayé d'utiliser jQuery pour rendre le formulaire de widget plus interactif/dynamique, mais cela ne semble pas fonctionner du tout. Par exemple, j'ai un bouton qui, une fois cliqué, ajoutera une chaîne de caractères "Hello!" à un div qui a id "ici".
<div id="here"></div>
<input type="button" id="add" value="Click Me!" " />
<script>
jQuery(document).ready(function(){
//call when the button is click
$(document).on('click', '#add', function() {
$('#here').append('<p>Hello</p>');
});
});
</script>
Pourquoi le paragraphe de "Bonjour" n'apparaît-il pas sur le formulaire? Est-ce parce que la forme du widget l'empêche de le faire?
J'ai aussi entendu parler de Backbone.js qui rafraîchit le front-end, mais je ne sais pas si cela fonctionnera.
Si possible, expliquez comment fonctionne la classe entière des widgets wordpress. Merci d'avance!
Mise à jour: j'ai déjà essayé ce qui est suggéré, mais cela ne fonctionne toujours pas. Voici mon code.
repeat.php
<?php
/**
* Plugin Name: Repeat Field
*
*/
class repeat_field_widget extends WP_Widget {
/**
* Sets up the widgets name etc
*/
public function __construct() {
$widget_ops = array(
'classname' => 'repeat_field_widget',
'description' => 'Repeat Field for Name input',
);
parent::__construct( 'repeat_field_widget', 'Repeat Field', $widget_ops );
}
/**
* Outputs the content of the widget
*
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
// outputs the content of the widget
}
/**
* Outputs the options form on admin
*
* @param array $instance The widget options
*/
public function form( $instance ) {
// outputs the options form on admin
?>
<div id="here"></div>
<input type="button" id="addRepeat" value="Click Me!" />
<?php
}
/**
* Processing widget options on save
*
* @param array $new_instance The new options
* @param array $old_instance The previous options
*/
public function update( $new_instance, $old_instance ) {
// processes widget options to be saved
}
}
function register_repeat_field_widget() {
register_widget( 'repeat_field_widget' );
}
add_action( 'widgets_init', 'register_repeat_field_widget' );
function repeat_field_widget_scripts() {
wp_enqueue_script( 'repeat-field-widget-scripts', get_template_directory_uri() . '/repeat.js', array( 'jquery' ), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'repeat_field_widget_scripts' );
repeat.js
jQuery(document).ready(function($){
//call when the button is click
$("#addRepeat").click(function() {
$('#here').append('<p>Hello</p>');
});
});
MerciDave RomseyetMark Kaplunpour avoir signalé le fait de ne pas utiliser d'identifiant HTML dans WordPress Widget. Je trouve enfin une solution à mon besoin.
Solution:
Nous devons ajouter des variables prédéfinies dans les 3 fonctions (widget, formulaire, mise à jour). Dans mes codes, ils s'appellent "spotlight_image_link1, spotlight_image_link2, etc.". Ensuite, dans la "fonction de formulaire", donnez leur identifiant en utilisant le code php. S'il vous plaît lire mon code ci-dessous pour plus d'informations.
Que peut faire ma solution?
Au fond, ce n’est pas totalement dynamique car il faut au préalable prédéfinir tous les projecteurs. Dans mon cas, je n'ai prédéfini que deux projecteurs pour simplifier la lecture du code.
Logique derrière la scène:
Limitation:
À partir de maintenant, chaque fois que nous avons cliqué sur "Enregistrer", l'ordre des projecteurs est réorganisé de 1 à n. Ce n'est pas très convivial, mais je prévois d'utiliser Ajax pour synchroniser le serveur frontal avec le serveur principal. Je ne sais pas encore comment.
Code source:
repeat.php
<?php
/**
* Plugin Name: Repeat Field
*
*/
class repeat_field_widget extends WP_Widget {
/**
* Sets up the widgets name etc
*/
public function __construct() {
$widget_ops = array(
'classname' => 'repeat_field_widget',
'description' => 'Repeat Field for Name input'
);
parent::__construct( 'repeat_field_widget', 'Repeat Field', $widget_ops );
$tracker1;
}
/**
* Outputs the content of the widget
*
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
// outputs the content of the widget
$spotlight_add_row = ! empty( $instance['spotlight_add_row'] ) ? $instance['spotlight_add_row'] : '';
$spotlight_row_appender = ! empty( $instance['spotlight_row_appender'] ) ? $instance['spotlight_row_appender'] : '';
/**============== Spotlight 1 =========================*/
$spotlight_image_link1 = ! empty( $instance['spotlight_image_link1'] ) ? $instance['spotlight_image_link1'] : '';
$spotlight_add_image1 = ! empty( $instance['spotlight_add_image1'] ) ? $instance['spotlight_add_image1'] : '';
$spotlight_image_preview1 = ! empty( $instance['spotlight_image_preview1'] ) ? $instance['spotlight_image_preview1'] : '';
$spotlight_name1 = ! empty( $instance['spotlight_name1'] ) ? $instance['spotlight_name1'] : '';
$spotlight_description1 = ! empty( $instance['spotlight_description1'] ) ? $instance['spotlight_description1'] : '';
$spotlight_link1 = ! empty( $instance['spotlight_link1'] ) ? $instance['spotlight_link1'] : '';
/**============== Spotlight 2 =========================*/
$spotlight_image_link2 = ! empty( $instance['spotlight_image_link2'] ) ? $instance['spotlight_image_link2'] : '';
$spotlight_add_image2 = ! empty( $instance['spotlight_add_image2'] ) ? $instance['spotlight_add_image2'] : '';
$spotlight_image_preview2 = ! empty( $instance['spotlight_image_preview2'] ) ? $instance['spotlight_image_preview2'] : '';
$spotlight_name2 = ! empty( $instance['spotlight_name2'] ) ? $instance['spotlight_name2'] : '';
$spotlight_description2 = ! empty( $instance['spotlight_description2'] ) ? $instance['spotlight_description2'] : '';
$spotlight_link2 = ! empty( $instance['spotlight_link2'] ) ? $instance['spotlight_link2'] : '';
}
/**
* Outputs the options form on admin
*
* @param array $instance The widget options
*/
public function form( $instance ) {
// outputs the options form on admin
$instance = wp_parse_args( (array) $instance, array( 'spotlight_add_row' => '', 'spotlight_row_appender' => '', 'spotlight_image_link1' => '', 'spotlight_add_image1' => '', 'spotlight_image_preview1' => '', 'spotlight_name1' => '', 'spotlight_description1' => '', 'spotlight_link1' => '',
'spotlight_image_link2' => '', 'spotlight_add_image2' => '', 'spotlight_image_preview2' => '', 'spotlight_name2' => '', 'spotlight_description2' => '', 'spotlight_link2' => '' ));
//Create Add and delete button
$spotlight_add_row = $instance['spotlight_add_row'];
$spotlight_row_appender = $instance['spotlight_row_appender'];
/**================== Spotlight 1 ==============*/
$spotlight_image_link1 = $instance['spotlight_image_link1'];
$spotlight_add_image1 = $instance['spotlight_add_image1'];
$spotlight_image_preview1 = $instance['spotlight_image_preview1'];
$spotlight_name1 = $instance['spotlight_name1'];
$spotlight_description1 = $instance['spotlight_description1'];
$spotlight_link1 = $instance['spotlight_link1'];
/**================== Spotlight 2 ==============*/
$spotlight_image_link2 = $instance['spotlight_image_link2'];
$spotlight_add_image2 = $instance['spotlight_add_image2'];
$spotlight_image_preview2 = $instance['spotlight_image_preview2'];
$spotlight_name2 = $instance['spotlight_name2'];
$spotlight_description2 = $instance['spotlight_description2'];
$spotlight_link2 = $instance['spotlight_link2'];
$starter = 1; //Store which number to continue adding spotlight.
$num = 1;
$max_spotlight = 2; //number of spotlight allowed.
static $tracker = array(0,0); //setup a tracker for each spotlight, zero mean none active.
while($num <= $max_spotlight){
$tempImage = 'spotlight_image_link' . $num;
if ($$tempImage != ''){
$starter++;
$tracker[$num - 1] = 1;
?>
<!-- Image input -->
<div>
<p class="spotlight-para">Spotlight <?php echo $num; ?></p>
<p> <?php $tempImage = 'spotlight_image_link' . $num; $tempDeleteName = 'deletespotlight_'. $num;?> <!-- store the combined name. -->
<label for="<?php echo esc_attr( $this->get_field_id( $tempImage ) ); ?>"><?php esc_attr_e( 'Image\'s link:', 'text_domain' ); ?></label>
<input
class="widefat"
id="<?php echo $this->get_field_id($tempImage); ?>"
name="<?php echo $this->get_field_name($tempImage); ?>"
type="text"
value="<?php echo esc_attr($$tempImage); ?>"
/>
<input style="float:right;" id="delete-spotlight" name="<?php echo $tempDeleteName; ?>" type="button" value="Delete Spotlight" class="button"/>
<br />
</p>
</div>
<?php
}
$num++;
}
$id_prefix = $this->get_field_id(''); //get the widget prefix id.
?>
<span id="<?php echo $this->get_field_id('spotlight_row_appender'); ?>"> </span>
<div>
<br />
<input
class="button"
type="button"
id="<?php echo $this->get_field_id('spotlight_add_row'); ?>"
value="Click Me!"
onclick="repeater.uploader('<?php echo $this->id;?>', '<?php echo $id_prefix;?>'); return false;"
/>
</div>
<script>
jQuery(document).ready(function($){
var tracker = <?php echo json_encode($tracker); ?>;
var c1 = <?php echo json_encode($starter - 1); ?>;//index of the array.
//disbale add button when reaches max spotlight.
if(tracker.every(x => x > 0)){
$('#' + '<?php echo $id_prefix; ?>' + 'spotlight_add_row').attr("disabled",true);
}
repeater = {
//TRY to mass Number into this function........
uploader :function(widget_id, widget_id_string){
//Find the non active element
var i;
for (i = 0; i < <?php echo $max_spotlight; ?>; i++){
if ( tracker[i] == 0){
c1 = i;
break;
}
}
c1++;
//alert(c1);
$("#" + widget_id_string + "spotlight_row_appender").append('<div> <p class="spotlight-para">Spotlight '+c1+'</p><p> <label for="<?php echo esc_attr( $this->get_field_id( "spotlight_image_link'+c1+'")); ?>"><?php esc_attr_e( 'Image\'s link:', 'text_domain' ); ?></label> <input class="widefat" id="<?php echo $this->get_field_id("spotlight_image_link'+c1+'"); ?>" name="<?php echo $this->get_field_name("spotlight_image_link'+c1+'"); ?>" type="text" value="" /> <input style="float:right;"id="delete-spotlight" name="deletespotlight_'+c1+'" type="button" value="Delete Spotlight" class="button"/><br /> </p></div>');
//check element as active
tracker[c1-1] = 1;
//if all element is > 0, disable the deleteButton.
if(tracker.every(x => x > 0)){
$('#' + '<?php echo $id_prefix; ?>' + 'spotlight_add_row').attr("disabled",true);
}
//alert(c1);
return false;
}
};
$(document).on('click', '#delete-spotlight', function() {
$(this).parent().parent().remove(); //remove the field.
$('#' + '<?php echo $id_prefix; ?>' + 'spotlight_add_row').removeAttr("disabled"); //reset add button.
//Get the name, and parse to get the ID.
var deleteButtonName = this.name;
var stringDeleteButton = deleteButtonName.split("_").pop();
var deleteButtonID = parseInt(stringDeleteButton);
tracker[deleteButtonID-1] = 0; //reset element
//alert(tracker);
});
});
</script>
<?php
}
/**
* Processing widget options on save
*
* @param array $new_instance The new options
* @param array $old_instance The previous options
*/
public function update( $new_instance, $old_instance ) {
// processes widget options to be saved
$instance = $old_instance;
$instance['spotlight_add_row'] = sanitize_text_field($new_instance['spotlight_add_row']);
$instance['spotlight_row_appender'] = sanitize_text_field($new_instance['spotlight_row_appender']);
$increment = 1;
while ( $increment <= 2 ){
//increment variables
$increment_image_link = 'spotlight_image_link' . $increment;
$increment_add_image = 'spotlight_add_image' . $increment;
$increment_image_preview = 'spotlight_image_preview' . $increment;
$increment_description = 'spotlight_description' . $increment;
$increment_name = 'spotlight_name' . $increment;
$increment_link = 'spotlight_link' . $increment;
$instance[$increment_image_link] = sanitize_text_field( $new_instance[$increment_image_link] );
$instance[$increment_add_image] = sanitize_text_field( $new_instance[$increment_add_image] );
$instance[$increment_image_preview] = sanitize_text_field( $new_instance[$increment_image_preview]);
$instance[$increment_name] = sanitize_text_field( $new_instance[$increment_name] );
$instance[$increment_description] = sanitize_text_field( $new_instance[$increment_description] );
$instance[$increment_link] = sanitize_text_field( $new_instance[$increment_link] );
$increment++;
}
$starter = 1;
$num = 1;
return $instance;
}
}
function register_repeat_field_widget() {
register_widget( 'repeat_field_widget' );
}
add_action( 'widgets_init', 'register_repeat_field_widget' );
Remarque rapide:
Je sais que ce n'est pas le code le plus propre, le plus sécurisé et le meilleur, mais j'apprends toujours. J'espère que cela aidera toute personne confrontée aux mêmes problèmes que moi.
Les formulaires de widget sont délicats pour la manipulation de JS. En général, vous ne devez jamais utiliser d'identifiants pour détecter des éléments dans le formulaire, mais une combinaison de classes et de find()
, parent()
etc.
La raison en est qu'il peut y avoir plus d'un formulaire sur la page HTML. Il est certain que sur la page d'administration du widget, un formulaire "modèle" ne s'affiche pas et IIRC est utilisé pour générer le formulaire d'un nouveau widget. Cela signifie qu'il y aura au moins deux éléments avec le même ID et qu'une tentative d'y accéder par les API DOM ne donnera pas un résultat cohérent.