Bagaimana cara menyimpan data bidang widget sebagai larik?

11

Saya membuat widget, perlu menyimpan sekitar 10 ID. Saat ini saya menggunakan metode bidang berikut untuk menyimpan masing-masing ID di bidang yang terpisah. Ini menyimpan data masing-masing bidang secara terpisah di wordpress. Apakah mungkin untuk menyimpan data semua bidang hanya dalam satu baris di wordpress untuk examlpe menggunakan array?

<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']; ?>" 
    />
jay
sumber
1
$instance adalah array dan berisi semua nilai. Dan apa yang Anda maksud dengan 'untuk menyimpan data semua bidang hanya dalam satu baris'? Apakah maksud Anda satu baris basis data?
Ralf912

Jawaban:

8

Anda harus mengumpulkan beberapa bidang dengan nama yang sama seperti ini ...

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

... dan sesuaikan logika widget Anda dengan ini.

Ini adalah widget demo yang sangat sederhana:

<?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

masukkan deskripsi gambar di sini

Paling depan

masukkan deskripsi gambar di sini

fuxia
sumber
+1 printfSintaks yang sangat elegan
Jawaban yang bagus untuk banyak bidang, tetapi mungkinkah ada pembaruan untuk memiliki 2 bidang secara berturut-turut? Saya mencoba menggunakan ini di widget saya tetapi saya harus memiliki 2 bidang berturut-turut seperti harga / tujuan, tetapi saya tidak tahu bagaimana cara mendapatkannya, saya selalu mendapatkan beberapa jenis kesalahan.
Aleksandar Đorđević
@ AleksandarĐorđević Cukup tulis HTML untuk itu, dan jangan gunakan class="widefat"untuk bidang.
fuxia
Jika saya hanya pintar seperti yang Anda pikirkan. Saya mengerti bahwa saya seharusnya menyimpannya di basis data sebagai bidang [0] [harga] dan bidang [0] [tujuan] dan seterusnya? tapi entah bagaimana saya tidak menyelesaikannya dengan benar.
Aleksandar Đorđević
Apakah mungkin foo menjadi array yang memiliki pasangan kunci / nilai?
worldwildwebdev
5

Jawaban di atas baik jika Anda membutuhkan bidang yang diberi nomor. Dalam kasus saya, saya tidak melakukannya. Saya memiliki widget dengan opsi yang memungkinkan pengguna memilih sejumlah kategori untuk digunakan dalam widget.

widget

Ini widget saya form. - Tiga hal penting di sini

  1. Pastikan nilai default menjadi kosong array()jika nilai widget tidak disetel
  2. Dalam <label> nameatribut formulir , perhatikan bahwa saya lampirkan []di bagian akhir. Ini memberi tahu PHP bahwa saya mengirimkan array nilai untuk kunci ini
  3. Bungkus kotak centang di label sebagai <label><input type="checkbox" ...></label>. - Setiap kotak centang kami tidak akan memiliki idatribut unik , sehingga <label> foratribut tidak akan berfungsi. Kami dapat membuat ID unik, tapi itu merepotkan. Jika Anda hanya membungkus label di sekitar input, label akan dikaitkan dengan benar tanpa perlu menghubungkan for+id

Sekarang kodenya

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
}

Dan inilah fungsi pembaruan saya

Saya tertarik untuk menyimpan ID Kategori dalam array, yang merupakan angka, jadi saya gunakan array_mapdengan intvaluntuk memastikan bahwa semua datum yang dikirimkan adalah bilangan bulat yang valid. Selain itu, saya gunakan array_filteruntuk menghapus kiriman yang tidak valid.

// @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']
  );
}

Sangat sulit untuk menggambarkan hal-hal WordPress ini. Jika Anda memiliki pertanyaan, saya akan dengan senang hati menjelaskan.


sumber