it-swarm.com.de

Wie speichere ich Widget-Felddaten als Array?

Ich erstelle ein Widget, es muss ungefähr 10 IDs speichern. Im Moment verwende ich die folgende Feldmethode, um jede der IDs in einem separaten Feld zu speichern. Es speichert die Daten jedes Feldes separat in WordPress. Ist es möglich, die Daten aller Felder in nur einer Zeile in WordPress zu speichern, beispielsweise mithilfe eines Arrays?

<input 
    class="widefat" 
    id="<?php echo $this->get_field_id('item1_id'); ?>" 
    name="<?php echo $this->get_field_name('item1_id'); ?>" 
    value="<?php echo $instance['item1_id']; ?>" 
    />

<input 
    class="widefat" 
    id="<?php echo $this->get_field_id('item2_id'); ?>" 
    name="<?php echo $this->get_field_name('item2_id'); ?>" 
    value="<?php echo $instance['item2_id']; ?>" 
    />
11
jay

Sie müssen mehrere Felder unter dem gleichen Namen wie folgt sammeln ...

name="collect[1]"
name="collect[2]"

… Und passen Sie Ihre Widget-Logik daran an.

Hier ist ein sehr einfaches Demo-Widget:

<?php  # -*- coding: utf-8 -*-
/* Plugin Name: Store Options as array */

add_action( 'widgets_init', array ( 'T5_Array_Options_Widget', 'register' ) );

class T5_Array_Options_Widget extends WP_Widget
{
    /**
     * Constructor.
     */
    public function __construct()
    {
        parent::__construct( strtolower( __CLASS__ ), 'Array Demo' );
    }

    /**
     * Echo the settings update form
     *
     * @param array $instance Current settings
     */
    public function form( $instance )
    {
        $title = isset ( $instance['title'] ) ? $instance['title'] : '';
        $title = esc_attr( $title );

        printf(
            '<p><label for="%1$s">%2$s</label><br />
            <input type="text" name="%3$s" id="%1$s" value="%4$s" class="widefat"></p>',
            $this->get_field_id( 'title' ),
            'Title',
            $this->get_field_name( 'title' ),
            $title
        );

        $fields = isset ( $instance['fields'] ) ? $instance['fields'] : array();
        $field_num = count( $fields );
        $fields[ $field_num + 1 ] = '';
        $fields_html = array();
        $fields_counter = 0;

        foreach ( $fields as $name => $value )
        {
            $fields_html[] = sprintf(
                '<input type="text" name="%1$s[%2$s]" value="%3$s" class="widefat">',
                $this->get_field_name( 'fields' ),
                $fields_counter,
                esc_attr( $value )
            );
            $fields_counter += 1;
        }

        print 'Fields<br />' . join( '<br />', $fields_html );
    }

    /**
     * Renders the output.
     *
     * @see WP_Widget::widget()
     */
    public function widget( $args, $instance )
    {
        print $args['before_widget']
        . $args['before_title']
        . apply_filters( 'widget_title', $instance['title'] )
        . $args['after_title']
        . join( '<br />', $instance['fields'] )
        . $args['after_widget'];
    }

    /**
     * Prepares the content. Not.
     *
     * @param  array $new_instance New content
     * @param  array $old_instance Old content
     * @return array New content
     */
    public function update( $new_instance, $old_instance )
    {
        $instance          = $old_instance;
        $instance['title'] = esc_html( $new_instance['title'] );

        $instance['fields'] = array();

        if ( isset ( $new_instance['fields'] ) )
        {
            foreach ( $new_instance['fields'] as $value )
            {
                if ( '' !== trim( $value ) )
                    $instance['fields'][] = $value;
            }
        }

        return $instance;
    }

    /**
     * Tell WP we want to use this widget.
     *
     * @wp-hook widgets_init
     * @return void
     */
    public static function register()
    {
        register_widget( __CLASS__ );
    }
}

Backend

enter image description here

Vorderes Ende

enter image description here

9
fuxia

Die obige Antwort ist gut, wenn die Felder nummeriert werden müssen. In meinem Fall habe ich nicht. Ich habe ein Widget mit Optionen, mit denen der Benutzer eine beliebige Anzahl von Kategorien auswählen kann, die im Widget verwendet werden sollen.

 widget 

Hier ist mein Widget form. - Drei wichtige Dinge hier

  1. Stellen Sie sicher, dass der Wert standardmäßig leer ist array(), wenn der Wert des Widgets nicht festgelegt ist
  2. Beachten Sie, dass ich im Formularattribut <label>name am Ende einen [] anhänge. Dies teilt PHP mit, dass ich ein Array von Werten für diesen Schlüssel übergebe
  3. Hängen Sie das Kontrollkästchen als <label><input type="checkbox" ...></label> in das Etikett ein. - Jedes unserer Kontrollkästchen hat kein eindeutiges Attribut id, daher funktioniert das Attribut <label>for nicht. Wir könnten eindeutige IDs generieren, aber das ist mühsam. Wenn Sie nur die Bezeichnung um die Eingabe wickeln, wird die Bezeichnung ordnungsgemäß zugeordnet, ohne dass die for + id mühsam verbunden werden muss.

Nun der Code

public function form($instance) {
  $title = isset($instance['title']) ? $instance['title'] : '';
  $categories = isset($instance['categories']) ? $instance['categories'] : array();
  ?>

  <p>
    <label for="<?php echo $this->get_field_id('title') ?>">
      <?php _e( 'Title:' ) ?>
    </label>
    <input class="widefat"
           id="<?php echo $this->get_field_id('title') ?>"
           name="<?php echo $this->get_field_name('title') ?>"
           value="<?php echo $title ?>" />
  </p>

  <p>Categories</p>
  <ul>
  <?php foreach (\get_categories() as $category): ?>
    <li>
      <label>
        <input type="checkbox"
             class="checkbox"
             name="<?php echo $this->get_field_name('categories') ?>[]"
             value="<?php echo $category->cat_ID ?>"
             <?php checked(in_array($category->cat_ID, $categories)) ?> />
        <?php echo $category->name ?>
      </label>
    </li>
  <?php endforeach ?>
  </ul>
  <?php
}

Und hier ist meine Update-Funktion

Ich möchte die Kategorie-IDs in einem Array speichern, bei dem es sich um Zahlen handelt. Daher verwende ich array_map mit intval, um sicherzustellen, dass alle übermittelten Daten gültige Ganzzahlen sind. Außerdem benutze ich array_filter, um ungültige Einsendungen zu entfernen.

// @param array $a - the new instance options
// @param arram $b - the old instance options
public function update($a, $b) {
  return array(
    'title'      => isset($a['title']) ? strip_tags($a['title']) : $b['title'],
    'categories' => isset($a['categories']) ? array_filter(array_map(function($id) { return intval($id); }, (array) $a['categories'])) : (array) $b['title']
  );
}

Es ist besonders schwierig, dieses WordPress-Zeug zu beschreiben. Wenn Sie Fragen haben, werde ich gerne näher darauf eingehen.

4
user633183