web-dev-qa-db-fra.com

Gutenberg: Obtenir tous les attributs du bloc "core/image"

Pour des raisons de conception/fonctionnalité, je voudrais changer la sortie du bloc core/image sur le frontend. Je sais que je pourrais le faire comme ça, mais c'est un peu lourd:

PHP:

// add my own render function for the core/image-block
register_block_type( 'core/image', [
    'render_callback' => 'myCustomImageOutput'
] );

function myCustomImageOutput( $attributes, $content ) {
    // thankfully, the ID is saved in $attributes
    $id = $attributes[ 'id' ];

    // all the other information is saved in $content as HTML
    // so one possible solution would be to parse it with DomDocument
    // and get all the values
    $dom = new DomDocument();

    // create custom image html

    // return custom image html
    return $customImageHtml;
}

Y a-t-il une meilleure façon d'obtenir tous les attributs?

1
uruk

En réponse à @RiddleMeThis , voici une solution fonctionnelle en analysant la sortie par défaut du bloc core/image- avec DOMDocument:

Dans la variable init-, enregistrez votre fonction de sortie personnalisée:

register_block_type( 'core/image', [
    'render_callback' => 'myImageOutput'
] );

Définissez votre fonction de sortie personnalisée:

Dans cette fonction, affiche le résultat par défaut ($content), qui est transmis en tant que deuxième argument. Malheureusement, le premier argument (étant le $attributes du bloc) ne contient pas les informations requises (à l'exception de l'ID de la pièce jointe et de la destination du lien).

function myImageOutput( $attributes, $content ) {
    // $content contains e.g.
    // <!-- wp:image {"id":123,"linkDestination":"custom"} -->
    // <figure class="wp-block-image"><a href="https://www.example.com"><img src="path/to/my/image.jpg" alt="Alternative text here" class="wp-image-123"/></a><figcaption>Caption goes here</figcaption></figure>
    // <!-- /wp:image -->

    // prepare array for all info. Note: alignment and customized 
    // size are ignored here since it was not required in this case
    $info = [
        'title' => '',
        'imagUrl' => '',
        'blank' => FALSE,
        'url' => '',
        'caption' => '',
    ];

    // Fortunately, the attachment id is saved in $attributes, so 
    // we can get the image's url
    $infos[ 'imageUrl' ] = wp_get_attachment_image_src( $attributes[ 'id' ], 'your-size' )[ 0 ];

    // we get the remaining info by loading the html via DOMDocument
    libxml_use_internal_errors( TRUE );
    $dom = new DOMDocument();
    $dom->preserveWhiteSpace = FALSE;
    $dom->loadHtml( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) );

    // get the figure element       
    $figure = $dom->getElementsByTagName( 'figure' )[ 0 ];

    // alternatively, get the image title or description etc. 
    // by querying it from the database
    $infos[ 'title' ] = $figure->getElementsByTagName( 'img' )[ 0 ]->getAttribute( 'alt' );

    // if we have a custom url on the image
    if ( isset( $attributes[ 'linkDestination' ] ) && $attributes[ 'linkDestination' ] == 'custom' ) {
        $a = $figure->getElementsByTagName( 'a' )[ 0 ];
        $infos[ 'url' ] = $a->getAttribute( 'href' );
        $infos[ 'blank' ] = strpos( $infos[ 'url' ], get_home_url() ) !== 0;
    }

    // caption, also see https://stackoverflow.com/a/2087136/1107529
    // because the caption can contain html
    $figCaption = $figure->getElementsByTagName( 'figcaption' );
    if ( count( $figCaption ) ) {
        $caption = '';
        foreach ( $figCaption[ 0 ]->childNodes as $child ) {
            $caption .= $dom->saveHTML( $child );
        }
        $infos[ 'caption' ] = $caption;
    }

    // create your custom html output here. In my case, I passed the 
    // info to a vue component
    $html = sprintf( '<my-custom-vue-component :info="%s"></my-custom-vue-component>', 
                esc_attr( json_encode( $info ) ) );

    return $html;
}

Cette solution fonctionne pour moi. Je suis sûr qu'il y aura une meilleure façon de le faire un jour, peut-être lorsque l'écosystème de Gutenberg aura mûri. Mais pour les moments, cela fonctionne sans problèmes.

J'espère que cela t'aides.

1
uruk