web-dev-qa-db-fra.com

Comment insérer plusieurs images dans une seule publication d'un CPT

J'ai créé un Custom Post Type pour publier plusieurs images ensemble.

--- >>> titre <<< ---
--- >>> image par défaut - miniature <<< ---
--- >>> cotent <<< ---
--- >>> images <<< ---
--- >>> images <<< ---
.....

Les trois premières sections (titre, image par défaut et contenu) constituent l'essentiel. Est prêt.

J'ai pensé à utiliser custom metabox et ajouter chaque URL d'image. Cependant, ajouter url by url n’a rien d’intuitif et représente beaucoup plus de travail pour l’utilisateur, qu’il soit novice ou avancé. En outre, le montant variera photos peut être 1, peut être 5 peut être 10 et ainsi de suite ....

Alors, comment puis-je ajouter plusieurs images dans un seul post CPT?

Le tableau de bord ressemblerait à ceci:

--- >>> titre <<< ---
--- >>> image par défaut - miniature <<< ---
--- >>> cotent <<< ---
--- >>> ajouter des images <<< ---

Comment puis-je faire ceci? Soyez un plugin ou direct dans function.php.

1
Zkk

MIS À JOUR

J? ai compris! J'ai fait de cette façon, j'ai créé une galerie dans l'éditeur WordPress. Et avec foreach, j'ai pris l'identifiant de chaque image et l'affiche dans la boucle:

<?php
global $post;
$gallery = get_post_gallery_images( $post );

foreach( $gallery as $image_url ) {
?>
<div class="item">
  <figure style="margin: 0px !important" itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
      <a href="<?php echo $image_url ?>" itemprop="contentUrl" data-size="1800x1200" data-index="0">
          <img src="<?php echo $image_url ?>" class="image" itemprop="thumbnail" alt="">
      </a>
  </figure>
</div>
<?php 
}
?>
0
Zkk

Comme vous le constatez à juste titre, l'enregistrement de l'URL n'est pas pratique pour les utilisateurs. En outre, cela n’est pas pratique pour le code, car il est difficile d’effectuer des opérations telles que l’affichage d’une taille d’image différente lorsque l’URL est tout ce que vous avez. Il est plutôt difficile de faire une inversion degenericde l'URL de l'image vers ses données de pièce jointe.

Pour le stockage, la pratique typique est de stocker les identifiants de pièces jointes. Ils sont conviviaux pour le stockage, l'interrogation, la sortie et résistent aux changements tels que le remplacement de la taille des images.

Malheureusement, de manière native, WP ne fournit qu'une interface permettant de stocker une seule image - image sélectionnée, c'est-à-dire une vignette.

Pour la structure que vous décrivez, les approches de base seraient:

  1. Stockez les vignettes en tant qu’image sélectionnée et reste d’images dans le contenu, à l’aide des fonctionnalités de galerie natives ou étendues de plug-ins. Cela fonctionne et est pratique/familier pour les utilisateurs, mais leur laisse plus d’espace pour le casser.
  2. Implémentez une méta-boîte personnalisée avec une interface personnalisée pour les images. Core n’a que peu d’aide à cet égard, mais il existe des cadres de champsmultiplespersonnalisés qui peuvent être utiles, c’est évidemment un cas d’utilisation courant. Cela rend le développement plus difficile, mais l'interface plus spécialisée et avec moins de marge d'erreur pour l'utilisateur.
1
Rarst

Si je comprends bien, vous devrez créer une méta-boîte avec des champs et utiliser jQuery pour ajouter/supprimer les zones d’image. Vous pouvez également utiliser l'interface utilisateur de jQuery pour rendre les champs déplaçables si vous le souhaitez.

Votre code de boîte méta ressemblera à quelque chose comme ça

// Fields
$prefix = 'your_prefix_';

$custom_meta_fields = array(
array(
   'label' => 'Gallery Images',
   'desc' => 'Add additional images for this portfolio item.',
   'id' => $prefix.'gallery_images',
   'scope' => array('your_custom_post_type'),
   'type' => 'repeatable_image',
),
);

// Add the Meta Box
function add_custom_meta_box()
{
    $post_types = array('your_custom_post_type', 'page', 'post');
    foreach ($post_types as $post_type) {
        add_meta_box(
            'custom_meta_box', // $id
            'Additional Information', // $title
            'show_custom_meta_box', // $callback
             $post_type,
            'normal', // $context
            'high' // $priority
        );
    }
}
add_action('add_meta_boxes', 'add_custom_meta_box');
// The Callback
function show_custom_meta_box()
{
    global $custom_meta_fields, $post;

// Use nonce for verification
echo '<input type="hidden" name="custom_meta_box_nonce" value="'.wp_create_nonce(basename(__FILE__)).'" />';
// Begin the field table and loop
echo '<table class="form-table">';

    foreach ($custom_meta_fields as $field) {
        //Check if scope matches post type
$scope = $field[ 'scope' ];
        $field_output = false;
        foreach ($scope as $scopeItem) {
            switch ($scopeItem) {
default: {
if ($post->post_type == $scopeItem) {
    $field_output = true;
}
break;
}
}
            if ($field_output) {
                break;
            }
        }
        if ($field_output) {
            // get value of this field if it exists for this post
$meta = get_post_meta($post->ID, $field['id'], true);
            $row = 0;
// begin a table row with
echo '<tr>
<th><label for="'.$field['id'].'">'.$field['label'].'</label></th>
<td>';
            switch ($field['type']) {
// text
case 'text':
echo '<input type="text" name="'.$field['id'].'" id="'.$field['id'].'" value="'.$meta.'" size="30" />
<br /><span class="description">'.$field['desc'].'</span>';
break;
// repeatable
case 'repeatable_image':
 echo '<a class="repeatable-add button" href="#">+</a>
         <ul id="'.$field['id'].'-repeatable" class="custom_repeatable">';
 $i = 0;
 if ($meta) {
     foreach ($meta as $row) {
         echo '<li><span class="sort hndle">|||</span>
                     <input type="text" class="img_field" name="'.$field['id'].'['.$i.']" id="'.$field['id'].'" value="'.$row.'" size="30" />
                     <a class="repeatable-remove button" href="#">-</a></li>';
         ++$i;
     }
 } else {
     echo '<li><span class="sort hndle">|||</span>
                 <input class="img_field" type="text" name="'.$field['id'].'['.$i.']" id="'.$field['id'].'" value="" size="30" />
                 <a class="repeatable-remove button" href="#">-</a></li>';
 }
 echo '</ul>
     <span class="description">'.$field['desc'].'</span>';
break;
} //end switch
echo '</td></tr>';
        }
    } // end foreach
echo '</table>'; // end table
}

// Save the Data
function save_custom_meta($post_id)
{
    global $custom_meta_fields;
// verify nonce
if (!isset($_POST['custom_meta_box_nonce']) || !wp_verify_nonce($_POST['custom_meta_box_nonce'], basename(__FILE__))) {
    return $post_id;
}
// check autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
    return $post_id;
}
// check permissions
if ('page' == $_POST['post_type']) {
    if (!current_user_can('edit_page', $post_id)) {
        return $post_id;
    } elseif (!current_user_can('edit_post', $post_id)) {
        return $post_id;
    }
}
// loop through fields and save the data
foreach ($custom_meta_fields as $field) {
    $old = get_post_meta($post_id, $field['id'], true);
    if (isset($_POST[$field['id']])) {
        $new = $_POST[$field['id']];
        if ($field['type'] === 'repeatable_ad' || $field['type'] === 'repeatable_image') {
            $new = array_values($new);
        }
    }
    if ($new && $new != $old) {
        update_post_meta($post_id, $field['id'], str_replace('"', "'", $new));
    } elseif ('' == $new && $old) {
        delete_post_meta($post_id, $field['id'], $old);
    }
} // end foreach
}
add_action('save_post', 'save_custom_meta');

et votre js devra être quelque chose comme ça

jQuery(document).on('click', '.img_field', function(e) {



var clicked_field = e.target.name;


var custom_uploader;


    e.preventDefault();

    //If the uploader object has already been created, reopen the dialog
    if (custom_uploader) {
        custom_uploader.open();
        return;
    }

    //Extend the wp.media object
    custom_uploader = wp.media.frames.file_frame = wp.media({
        title: 'Select Image',
        button: {
            text: 'Select Image'
        },
        multiple: false
    });

    //When a file is selected, grab the URL and set it as the text field's value
    custom_uploader.on('select', function() {
        attachment = custom_uploader.state().get('selection').first().toJSON();
        jQuery('input[name="'+ clicked_field +'"]').val(attachment.url);
        jQuery('.custom_preview_image').attr('src', attachment.url);
        jQuery('.custom_media_image').attr('src',attachment.url);
    });

    //Open the uploader dialog
    custom_uploader.open();

});


jQuery('.repeatable-add').click(function() {
    field = jQuery(this).closest('td').find('.custom_repeatable li:last').clone(true);
    fieldLocation = jQuery(this).closest('td').find('.custom_repeatable li:last');
    jQuery('input', field).val('').attr('name', function(index, name) {
        return name.replace(/(\d+)/, function(fullMatch, n) {
            return Number(n) + 1;
        });
    })
    field.insertAfter(fieldLocation, jQuery(this).closest('td'))
    return false;
});

jQuery('.repeatable-remove').click(function(){
    jQuery(this).parent().remove();
    return false;
});

jQuery('.custom_repeatable').sortable({
    opacity: 0.6,
    revert: true,
    cursor: 'move',
    handle: '.sort'
});

Je n'ai pas testé cela, alors laissez-moi savoir si cela ne fonctionne pas, mais cela devrait vous donner une bonne longueur d'avance. Cela dit, il est beaucoup plus facile d’utiliser ACF ou CMB2 pour faire ce genre de chose. Quoi qu'il en soit, j'espère que cela aide.

1
user53340

Le plug-in de champ personnalisé avancé fournit cette fonctionnalité par le biais d'un ajout supplémentaire appelé champ de répéteur acf www.advancedcustomfields.com/resources/repeater dans lequel vous pouvez ajouter le même champ plusieurs fois dans une publication.

0
Unnikrishnan R