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
.
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
}
?>
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:
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.
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.