Administrer le quatriĂšme format d’images de WordPress

Le sujet des images dans WordPress peut ĂȘtre sensible surtout quand on se prĂ©occupe un peu de son espace disque 😅

Si on laisse de cĂŽtĂ© les thĂšmes premium et leur mille formats d’images gĂ©nĂ©rĂ©s pour pas grand chose (je hais les thĂšmes premium !) , il faut savoir que lorsqu’on tĂ©lĂ©verse une image dans WordPress ce dernier va par dĂ©faut en crĂ©er quatre autres.
MĂȘme s’il vous semble que l’administration WordPress vous offre la possibilitĂ© de prĂ©ciser vos tailles d’images : « Taille des miniatures », « Taille moyenne » et « Grande taille Â», WordPress gĂšre en fait une quatriĂšme taille medium_large qu’il utilise pour les images responsives đŸ€”

Si vous avez loupĂ© ce dĂ©tail datant du 22 dĂ©cembre 2015 (version 4.4 de WordPress), voici l’article qui y fait rĂ©fĂ©rence : Responsive Images in WordPress 4.4.

Du coup, en parcourant le code du cƓur, il est facile de trouver dans wp-admin/includes/schema.php les deux options qui font rĂ©fĂ©rence Ă  la taille de cette image :

// 4.4.0
'medium_large_size_w' => 768,
'medium_large_size_h' => 0,

Je n’ai pas poussĂ© jusqu’Ă  trouver le ticket qui fait rĂ©fĂ©rence Ă  ce choix de 768px mais je suis presque sĂ»r que c’est parce que cela correspond Ă  la largeur CSS d’un Ipad đŸ˜†
Quel malheur đŸ˜„

Comme j’ai pu ĂȘtre mauvaise langue 😜 en disant que je n’avais jamais rien trouvĂ© dans le codex au sujet de ce format, je m’en excuse car tout y est, il suffit d’ouvrir les yeux : Featured Images & Post Thumbnails

Bon bĂ© maintenant qu’on est au courant, il ne reste plus qu’Ă  nous offrir la possibilitĂ© de prĂ©ciser les dimensions maximales (en pixels) Ă  utiliser pour ce fameux format Â« Medium-large » comme ci-dessous.

La premiĂšre chose Ă  faire est de rajouter les champs de saisie au bon endroit :

/**
 * Adds a new field into the media settings page to manage
 * the fourth image size: "Medium Large".
 *
 * Introduced by WordPress 4.4, this format has by default a `768px` width
 * and is used for responsive images (through the `srcset` attribute).
 * I know that it's not a good idea to define `srcset` and `size`
 * attributes according to this site breakpoint
 * (cf.: )
 * but as WP handles this format (and uses space disc) without telling us,
 * we should be able to edit it to enjoy it even for one of our breakpoints.
 *
 * If you want to escape this format, you just have to set its width
 * and height to zero ;)
 */
function thistle_add_medium_large_size_settings() {
    add_settings_field(
        'medium_large_size',
        __( 'Large size' ),
        '_thistle_output_medium_large_size_settings',
        'media',
        'default',
        array()
    );
}

function _thistle_output_medium_large_size_settings() {
    ?>
    <fieldset>
        <legend class="screen-reader-text">
            <span><?php _e( 'Large size' ); ?></span>
        </legend>
        <label for="medium_large_size_w"><?php _e( 'Max Width' ); ?></label>
        <input name="medium_large_size_w" type="number" step="1" min="0" id="medium_large_size_w" value="<?php form_option( 'medium_large_size_w' ); ?>" class="small-text" />
        <br>
        <label for="medium_large_size_h"><?php _e( 'Max Height' ); ?></label>
        <input name="medium_large_size_h" type="number" step="1" min="0" id="medium_large_size_h" value="<?php form_option( 'medium_large_size_h' ); ?>" class="small-text" />
    </fieldset>
    <?php
}
add_action( 'admin_init', 'thistle_add_medium_large_size_settings' );

Je l’avoue, j’ai pris une initiative supplĂ©mentaire dans mon code 😚

Comme en bon François Â« Medium-large » ne semble pas avoir d’Ă©quivalent, j’ai dĂ©cidĂ© que ce format s’appellerait maintenant « Grande taille » et que je renommerais le prĂ©cĂ©dent Â« Grande taille » en « TrĂšs grande taille » đŸ€“

Procédons donc au renommage :

/**
 * Renames "Large" label into "Extra large" via JavaScript 
 * because we can't do it with the help of PHP.
 */
function thistle_rename_large_size_settings() {
    ?>
    <script>
        ( function( window, $, undefined ) {
            if ( typeof $ !== 'undefined' ) {
                $( document ).ready( function () {
                    var $lss = $( '#large_size_w' ).parents('tr');

                    $lss
                        .find('th, legend span')
                            .html('<?php _e( 'Extra large size', YOUR_TEXT_DOMAIN ); ?>');
                } );
            }
        } )( window, window.jQuery );
    </script>
    <?php
}
add_action( 'admin_head-options-media.php', 'thistle_rename_large_size_settings' );

/**
 * Retrieves the names and labels of the default image sizes including
 * the fourth (or fifth) one: "Medium Large".
 * Because we don't have a good translation for "Medium Large" in French,
 * I decided to rename "Large" into "Extra large" and
 * give the "Large" label to the medium_large size.
 *
 * @param array $size_names Array of image sizes and their names. Default values
 *                          include 'Thumbnail', 'Medium', 'Large', 'Full Size'.
 * @return array
 */
function thistle_change_image_size_names( $size_names ) {
    $index = array_search( 'large' , array_keys( $size_names ) );

    $size_names = array_merge( array_slice( $size_names, 0, $index, true), array( 'medium_large' => _( 'Large' ) ), $size_names );
    $size_names['large'] = __( 'Extra large', YOUR_TEXT_DOMAIN );

    return $size_names;
}
add_filter( 'image_size_names_choose', 'thistle_change_image_size_names' );

Je sais que ce choix peut ĂȘtre sujet Ă  un troll monumental mais je l’assume đŸ˜Ž On aurait aussi pu traduire Â« Medium-large » par Â« Taille intermĂ©diaire » mais bon.

Nous y sommes presque.
Quand nous avons ajoutĂ© nos champs via add_settings_field, ces derniers se sont placĂ©s Ă  la fin de notre page et ce n’est pas vraiment logique par rapport Ă  l’ordre des tailles d’images.

Remettons cela dans le bon ordre :

/**
 * Changes the order of the size settings to have "Medium Large" before
 * "Large" via JavaScript because we can't do it with the help of PHP.
 */
function thistle_change_size_settings_order() {
    ?>
    <script>
        ( function( window, $, undefined ) {
            if ( typeof $ !== 'undefined' ) {
                $( document ).ready( function () {
                    var $lss = $( '#large_size_w' ).parents('tr');
                    var $mlss = $( '#medium_large_size_w' ).parents('tr');

                    $lss
                        .insertAfter($mlss);
                } );
            }
        } )( window, window.jQuery );
    </script>
    <?php
}
add_action( 'admin_head-options-media.php', 'thistle_change_size_settings_order' );

Je ne vous cache pas que l’utilisation de JavaScript pour faire ce genre de choses ne m’enchante jamais mais quand WordPress ne nous laisse pas le choix
 đŸ˜©

Sauf que, mĂȘme si nos nouveaux champs se trouvent bien sur notre page d’options et  sont dans le bon ordre, les nouvelles dimensions ne s’enregistrent pas en base de donnĂ©es đŸ€”
Pour que cela fonctionne, nous devons whitelister celles-ci de la façon suivante :

/**
 * Adds the `medium_large_size_w` and `medium_large_size_h` options
 * to the white list to be authorised to edit them.
 *
 * @param array White list options.
 * @return array.
 */
function thistle_media_whitelist_options( $whitelist_options ) {
    $whitelist_options['media'][] = 'medium_large_size_w';
    $whitelist_options['media'][] = 'medium_large_size_h';
    
    return $whitelist_options;
}
add_filter( 'whitelist_options', 'thistle_media_whitelist_options' );

Voila, c’est fini đŸ˜