web-dev-qa-db-fra.com

Ajouter un attribut au sous-code de la légende à partir du champ de pièce jointe personnalisée

Je veux ajouter une classe au shortcode de la légende, extraite du champ de pièce jointe personnalisée. J'ajoute le champ via:

function add_img_class( $form_fields, $post ) {
    $form_fields['img_class_field'] = array(
        'label' => __( 'Image class', 'text-domain' ),
        'input' => 'text',
        'value' => get_post_meta( $post->ID, 'img_class_field', true )
    );
    return $form_fields;
}

add_filter( 'attachment_fields_to_edit', 'add_img_class', 10, 2 );


function save_img_class( $post, $attachment ) {
    if( isset( $attachment['img_class_field'] ) )
        update_post_meta( $post['ID'], 'img_class_field', $attachment['img_class_field']);
    return $post;
}

add_filter( 'attachment_fields_to_save', 'save_img_class', 10, 2 );

Comment ajouter dynamiquement un attribut "class" avec la valeur de champ au sous-code shortcode maintenant?

[caption ... class="img_class_field"]<img src...>[/caption]
1
Runnick

Voici une solution qui exploite le filtre shortcode_atts_{shortcode}, où caption est le shortcode dans ce cas.

Cela fonctionne en tirant l'ID de pièce jointe de $out['id'] puis en obtenant la valeur de la classe via get_post_meta( $attachment_id, 'img_class_field', true ).

Avec cette approche, il n'est pas nécessaire de modifier la sortie du shortcode de légende dans l'éditeur. L'ajout de la classe personnalisée est géré en arrière-plan. Cela fonctionne également si un utilisateur a ajouté manuellement un attribut de classe au shortcode de la légende.

/**
 * Adds class to caption shortcode output via img_class_field attachment meta.
 *
 * @param array  $out       The output array of shortcode attributes.
 * @param array  $pairs     The supported attributes and their defaults.
 * @param array  $atts      The user defined shortcode attributes.
 * @param string $shortcode The shortcode name.
 */
add_filter( 'shortcode_atts_caption', 'wpse_shortcode_atts_caption', 10, 4 );
function wpse_shortcode_atts_caption( $out, $pairs, $atts, $shortcode ) {
    // Get the attachment id. It should be available via $out['id'], but
    // it will be in the format 'attachment_xxxx' where xxxx is the id.
    // We'll try to get the id portion and we'll bail if this doesn't work.
    $attachment_id = isset( $out['id'] ) && ( $out['id'] ) ? $out['id'] : false;
    $attachment_id = (int) preg_replace( '/^attachment_/', '', $attachment_id );
    if ( ! $attachment_id ) {
        return $out;
    }

    // Get the custom image class and add it to the existing classes
    $extra_image_class = get_post_meta( $attachment_id, 'img_class_field', true );
    if ( $extra_image_class ) {
        $spacer = isset( $out['class'] ) && ( $out['class'] ) ? ' ' : '';
        $out['class'] .= esc_attr( $spacer . $extra_image_class );
    }

    return $out;
}

Usage

Classes personnalisées ajoutées aux méta-données de pièce jointe (j'ai utilisé 2 pour une bonne mesure):

some-class another-class

Exemple de shortcode de légende non modifié ajouté via le média modal:

[caption id="attachment_2397" align="alignnone" width="480"]<a href="http://example.com/wp-content/uploads/2017/05/image.jpg"><img src="http://example.com/wp-content/uploads/2017/05/image.jpg" alt="" width="480" height="360" class="size-full wp-image-2397" /></a> This is the caption![/caption]

Exemple de sortie 1:( prise en charge du thème HTML5 pour les légendes):

<figure id="attachment_2397" style="width: 480px" class="wp-caption alignnone some-class another-class">
    <a href="http://example.com/">
        <img src="http://example.com/wp-content/uploads/2017/05/image.jpg" alt="" width="480" height="360" class="size-full wp-image-2397" srcset="http://example.com/wp-content/uploads/2017/05/image.jpg 480w, http://example.com/wp-content/uploads/2017/05/image-300x225.jpg 300w" sizes="(max-width: 480px) 100vw, 480px">
    </a>
    <figcaption class="wp-caption-text">This is the caption!</figcaption>
</figure>

Exemple de sortie 2:(le thème ne prend pas en charge HTML5 pour les légendes):

<div id="attachment_2397" style="width: 490px" class="wp-caption alignnone some-class another-class">
    <a href="http://example.com/wp-content/uploads/2017/05/image.jpg">
        <img src="http://example.com/wp-content/uploads/2017/05/image.jpg" alt="" width="480" height="360" class="size-full wp-image-2397" srcset="http://example.com/wp-content/uploads/2017/05/image.jpg 480w, http://example.com/wp-content/uploads/2017/05/image-300x225.jpg 300w" sizes="(max-width: 480px) 100vw, 480px">
    </a>
    <p class="wp-caption-text">This is the caption!</p>
</div>
1
Dave Romsey

Mon idée derrière ceci serait d'utiliser réellement un appel de champ personnalisé dans le shortcode lui-même, puis d'ajouter un filtre shortcode_atts _ {$ shortcode} pour traiter ledit champ personnalisé et l'ajouter à la classe pour le retourner.

{shortcode} dans ce cas serait caption puisque c'est ce que nous construisons.

add_filter( 'shortcode_atts_caption', 'caption_custom_field_class' );

function caption_custom_field_class( $out, $pairs, $atts, $shortcode ) {
    if ( !empty( $atts['custom_field'] ) && get_post_meta( sanitize_text( $atts['custom_field'] ), $atts['id'], true ) ) {
             $out['class'] .= ( !empty( $out['class'] ) ? ' ' : '' ) . get_post_meta( sanitize_text( $atts['custom_field'] ), $atts['id'], true );
        }
    }
    return $out;
}

Nous utilisons donc un autre champ de variable appelé 'custom_field' pour transmettre notre nom de champ personnalisé.

[caption custom_field="mycustomfieldname"]<img src=".... />[/caption]

La fonction vérifie si l'attribut custom_field shortcode est vide ou non, et vérifie si vous pouvez récupérer une méta de publication en fonction de l'ID transmis. Si les deux sont vrais, l'ajoute à $out['class'] avec un espace selon que $out['class'] est vide ou non.

Je devrais peut-être mettre à jour cette réponse, car j'ai commencé à écrire ici et je vais l'essayer dans un environnement réel.

1
socki03