@alexiusgrey

Как сделать таким способом 2+ метабокса?

Хочу создать несколько метабоксов с разной галереей внутри каждого.
ДА, Я ЗНАЮ ПРО ACF, я хочу именно для себя научиться нативно-кодом-руками - я люблю докапываться как все устроено, но не без того, чтобы заходить в тупики. Я нашел вот такой способ создать метабокс с галереей, и когда я добавляю только один метабокс, все сохраняется, работает и выводится отлично и без проблем
function gallery_metabox_enqueue($hook) {
  if ( 'post.php' == $hook || 'post-new.php' == $hook ) {
    wp_enqueue_script('gallery-metabox', get_template_directory_uri() . '/js/gallery-metabox.js', array('jquery', 'jquery-ui-sortable'));
    wp_add_inline_style( 'gallery-metabox', '#gallery-metabox-list li {float: left; width: 30%; text-align: center; margin: 10px 10px 10px 0;  cursor: move;}' );
  }
}
add_action('admin_enqueue_scripts', 'gallery_metabox_enqueue');

function gallery_meta_save($post_id) {
  if (!isset($_POST['gallery_meta_nonce']) || !wp_verify_nonce($_POST['gallery_meta_nonce'], basename(__FILE__))) {
    return;
  }

  if (!current_user_can('edit_post', $post_id)) {
    return;
  }

  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
    return;
  }

  if (isset($_POST['gallery_images']) && is_array($_POST['gallery_images'])) {
    $images = array_map('sanitize_text_field', $_POST['gallery_images']);
    update_post_meta($post_id, 'gallery_images', $images);
  }
}
add_action('save_post', 'gallery_meta_save');

function gallery_meta_callback($post) {
  wp_nonce_field(basename(__FILE__), 'gallery_meta_nonce');
  $gallery_images = get_post_meta($post->ID, 'gallery_images', true);
  ?>
  <table class="form-table">
    <tr>
      <td>
        <ul id="gallery-metabox-list">
          <?php if ($gallery_images) : ?>
            <?php foreach ($gallery_images as $image_id) : ?>
              <li>
                <?php echo wp_get_attachment_image($image_id, 'thumbnail'); ?>
                <input type="hidden" name="gallery_images[]" value="<?php echo esc_attr($image_id); ?>">
                <a class="remove-image" href="#">Remove image</a>
              </li>
            <?php endforeach; ?>
          <?php endif; ?>
        </ul>
        <a class="gallery-add button" href="#" data-uploader-title="Add image(s) to gallery" data-uploader-button-text="Add image(s)">Add Images</a>
      </td>
    </tr>
  </table>
  <?php
}

function add_gallery_metabox($post_type) {
  add_meta_box(
    'gallery-metabox',
    'Gallery',
    'gallery_meta_callback',
    $post_type,
    'normal',
    'high'
  );
}
add_action('add_meta_boxes', 'add_gallery_metabox');

JS-часть, файл gallery-metabox.js
jQuery(function($) { 
  var file_frame;

  $(document).on('click', 'a.gallery-add', function(e) {
    e.preventDefault();

    if (file_frame) {
      file_frame.open();
      return;
    }

    file_frame = wp.media({
      title: $(this).data('uploader-title'),
      button: {
        text: $(this).data('uploader-button-text'),
      },
      multiple: true
    });

    file_frame.on('select', function() {
      var list = $('#gallery-metabox-list'),
        selection = file_frame.state().get('selection');

      selection.each(function(attachment) {
        attachment = attachment.toJSON();
        list.append('<li><input type="hidden" name="gallery_images[]" value="' + attachment.id + '"><img class="image-preview" src="' + attachment.sizes.thumbnail.url + '"><a class="remove-image" href="#">Remove image</a></li>');
      });
    });

    file_frame.open();
  });

  $(document).on('click', 'a.remove-image', function(e) {
    e.preventDefault();
    $(this).parent().remove();
  });
});

Но когда пробую добавить еще один метабокс, то фотографии загружаются, но не сохраняются. Я писал GPT, оно мне сказало глянуть в логи, там "дата" картинок тогда не передается. Ничего не помогло, что оно мне советовало. Вот когда один метабокс - то все работает и выводится, а два и больше - уже нет. Так что это не "конфликт плагинов" - так бы не работал и один, и у меня очень мало плагинов. на метабоксы нету никакого, acf нету и близко.
Один из вариантов что пробовал, но пробовал разное, а код длинный. Покажите пожалуйста правильный пример с двумя метабоксами-галереями - пример с текстом не помог.
function add_gallery_metaboxes($post_type) {
  $types = array('post', 'product', 'custom-post-type');

  if (in_array($post_type, $types)) {
    // Add the first metabox
    add_meta_box(
      'gallery-metabox-first', // Unique identifier for the first metabox
      'Gallery First', // Title of the first metabox
      'gallery_meta_callback_first', // Callback function to display the first metabox content
      $post_type,
      'normal',
      'high',
      array('id' => 'first') // Pass a unique ID as an argument
    );

    // Add the second metabox
    add_meta_box(
      'gallery-metabox-second', // Unique identifier for the second metabox
      'Gallery Second', // Title of the second metabox
      'gallery_meta_callback_second', // Callback function to display the second metabox content
      $post_type,
      'normal',
      'high',
      array('id' => 'second') // Pass a unique ID as an argument
    );
  }
}
add_action('add_meta_boxes', 'add_gallery_metaboxes');

function gallery_meta_callback_first($post, $metabox) {
  wp_nonce_field(basename(__FILE__), 'gallery_meta_nonce_first');

  $gallery_id = isset($metabox['args']['id']) ? $metabox['args']['id'] : 'first'; // Get the unique ID

  ?>
  <table class="form-table">
    <tr>
      <td>
        <ul id="gallery-metabox-list-<?php echo $gallery_id; ?>" style="display:flex; flex-wrap:wrap;gap: 10px;">
          <!-- Your code to display images and input fields for the first metabox here -->
        </ul>
        <a class="gallery-add button" href="#" data-gallery-id="<?php echo $gallery_id; ?>" data-uploader-title="Add image(s) to gallery" data-uploader-button-text="Add image(s)">Add Images</a>
      </td>
    </tr>
  </table>
  <?php
}

function gallery_meta_callback_second($post, $metabox) {
  wp_nonce_field(basename(__FILE__), 'gallery_meta_nonce_second');

  $gallery_id = isset($metabox['args']['id']) ? $metabox['args']['id'] : 'second'; // Get the unique ID

  ?>
  <table class="form-table">
    <tr>
      <td>
        <ul id="gallery-metabox-list-<?php echo $gallery_id; ?>" style="display:flex; flex-wrap:wrap;gap: 10px;">
          <!-- Your code to display images and input fields for the second metabox here -->
        </ul>
        <a class="gallery-add button" href="#" data-gallery-id="<?php echo $gallery_id; ?>" data-uploader-title="Add image(s) to gallery" data-uploader-button-text="Add image(s)">Add Images</a>
      </td>
    </tr>
  </table>
  <?php
}


jQuery(function($) { 
  function handleGalleryMetabox(gallery_id) {
    var file_frames = {};

    $(document).on('click', 'a.gallery-add', function(e) {
      e.preventDefault();

      if (!file_frames[gallery_id]) {
        file_frames[gallery_id] = wp.media({
          title: $(this).data('uploader-title'),
          button: {
            text: $(this).data('uploader-button-text'),
          },
          multiple: true
        });

        file_frames[gallery_id].on('select', function() {
          var list = $('#gallery-metabox-list-' + gallery_id),
            listIndex = list.find('li').length,
            selection = file_frames[gallery_id].state().get('selection');

          selection.each(function(attachment) {
            attachment = attachment.toJSON();
            list.append('<li><input type="hidden" name="' + gallery_id + '[' + listIndex + ']" value="' + attachment.id + '"><img class="image-preview" src="' + attachment.sizes.thumbnail.url + '"><a class="change-image button button-small" href="#" data-uploader-title="Change image" data-uploader-button-text="Change image">Change image</a><br><small><a class="remove-image" href="#">Remove image</a></small></li>');
            listIndex++;
          });

          makeSortable(gallery_id);
        });
      }

      file_frames[gallery_id].open();
    });

    function resetIndex(gallery_id) {
      $('#gallery-metabox-list-' + gallery_id + ' li').each(function(i) {
        $(this).find('input:hidden').attr('name', gallery_id + '[' + i + ']');
      });
    }

    function makeSortable(gallery_id) {
      $('#gallery-metabox-list-' + gallery_id).sortable({
        opacity: 0.6,
        stop: function() {
          resetIndex(gallery_id);
        }
      });
    }

    $(document).on('click', 'a.remove-image', function(e) {
      e.preventDefault();

      var gallery_id = $(this).data('gallery-id'); // Get the gallery ID

      $(this).parents('li').animate({ opacity: 0 }, 200, function() {
        $(this).remove();
        resetIndex(gallery_id);
      });
    });
  }

  // Handle the first gallery metabox
  handleGalleryMetabox('first');
  
  // Handle the second gallery metabox
  handleGalleryMetabox('second');
});
  • Вопрос задан
  • 48 просмотров
Пригласить эксперта
Ответы на вопрос 1
Наводка
function gallery_meta_save($post_id) {
  if (!isset($_POST['gallery_meta_nonce']) || !wp_verify_nonce($_POST['gallery_meta_nonce'], basename(__FILE__))) {
    return;
  }

  if (!current_user_can('edit_post', $post_id)) {
    return;
  }

  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
    return;
  }

  if (isset($_POST['gallery_images']) && is_array($_POST['gallery_images'])) {
    $images = array_map('sanitize_text_field', $_POST['gallery_images']);
    update_post_meta($post_id, 'gallery_images', $images);
  }

  if (isset($_POST['gallery_images_2']) && is_array($_POST['gallery_images_2'])) {
    $images_2 = array_map('sanitize_text_field', $_POST['gallery_images_']);
    update_post_meta($post_id, 'gallery_images_2', $images_2);
  }
}

Соответственно, продублировать функцию gallery_meta_callback() с постфиксом _2

js не смотрел
Данный метод подойдет только для 2х галерей

Если нужно больше таких окон, то тут уже нужно придумывать счетчик с перебором
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы