WPmagus - magicy od WordPressa

Czar metalowych czcionek

Krzysiek Dróżdż
krzysiek@wpmagus.pl
WPmagus.pl

Nadchodzi rewolucja?

Kto słyszał?

Kto widział?

No to zobaczmy

Tylko jak??

Wystarczy pobrać wtyczkę: https://wordpress.org/plugins/gutenberg/

A po jej włączeniu

To

Staje się tym

A co da się z tym zrobić?

Co z własnymi typami wpisów?

Muszą spełnić dwa warunki

  • wsparcie edytora:
    'supports' => array( 'title', 'editor', 'author', ... ),
  • obecność w REST API:
    'show_in_rest' => true

A jeśli jednak nie chcemy Gutenberga?

add_filter(
    'gutenberg_can_edit_post_type',
    function( $can_edit, $post_type_slug ) {
        if ( 'book' === $post_type_slug ) {
            return false;
        }
        return $can_edit;
    },
    10, 2
);

Wprowadźmy ograniczenia...?

Pozwólmy tylko na niektóre bloki

add_filter( 'allowed_block_types', function( $allowed_block_types, $post ) {
    if ( 'book' === $post->post_type ) {
        return [ 'core/paragraph', 'core/quote', 'core/heading' ];
    }
    return $allowed_block_types;
}, 10, 2 );

… lub wyłączmy je wszystkie

add_filter( 'allowed_block_types', function( $allowed_block_types, $post ) {
    if ( 'book' === $post->post_type ) {
        return false;
    }
    return $allowed_block_types;
}, 10, 2 );

Niech zapanuje porządek

Zdefiniujmy szablon

add_action( 'init', function() {
    $post_type_object = get_post_type_object( 'book' );
    $post_type_object->template = array(
        array( 'core/paragraph', array(
            'placeholder' => 'Dodaj zajawkę...',
        ) ),
        array( 'core/quote', array(
            'placeholder' => 'Dodaj chwytliwy cytat...',
        ) ),
        array( 'core/paragraph', array(
            'placeholder' => 'Dodaj opis...',
        ) ),
    );
}, 20, 0 );

I zablokujmy jego zmiany

add_action( 'init', function() {
    $post_type_object = get_post_type_object( 'book' );
    $post_type_object->template = array(
        array( 'core/paragraph', array(
            'placeholder' => 'Dodaj zajawkę...',
        ) ),
        array( 'core/quote', array(
            'placeholder' => 'Dodaj chwytliwy cytat...',
        ) ),
        array( 'core/paragraph', array(
            'placeholder' => 'Dodaj opis...',
        ) ),
    );
    $post_type_object->template_lock = 'all';
}, 20, 0 );

Można też w trakcie rejestrowania CPT

add_action( 'init', function() {
$args = array(
    'labels'             => $labels,
    'description'        => __( 'Description.', 'your-plugin-textdomain' ),
    ...
    'show_in_rest'       => true,
    template             => array(
            array( 'core/paragraph', array(
                'placeholder' => 'Dodaj zajawkę...',
            ) ),
            array( 'core/quote', array(
                'placeholder' => 'Dodaj chwytliwy cytat...',
            ) ),
            ...
        )
);
register_post_type( 'book', $args );

Stwórzmy własny blok

add_action( 'enqueue_block_editor_assets', function() {
    wp_enqueue_script(
        'wpmagus-review-block',
        plugins_url( 'review-block.js', __FILE__ ),
        array( 'wp-blocks', 'wp-element' )
    );
} );


add_action( 'enqueue_block_assets', function() {
    wp_enqueue_style(
        'wpmagus-review-block-style',
        plugins_url( 'review-block.css', __FILE__ ),
        array( 'wp-blocks' )
    );
} );

Szkielet i właściwości

var el = wp.element.createElement,
    i18n = wp.i18n,
    components = wp.components,
    blocks = wp.blocks,
    registerBlockType = blocks.registerBlockType,
    RichText = blocks.RichText,
    BlockControls = blocks.BlockControls,
    AlignmentToolbar = blocks.AlignmentToolbar;

registerBlockType( 'wpmagus/review', {
    title: 'Review',
    icon: 'testimonial',
    category: 'common',

    attributes: {
        name: {
            type: 'array',
            source: 'children',
            selector: 'p.wpmagus-reviewer-name',
        },
        review: {
            type: 'array',
            source: 'children',
            selector: 'p',
        },
        mediaID: {
            type: 'number',
        },
        mediaURL: {
            type: 'string',
            source: 'attribute',
            selector: 'img',
            attribute: 'src',
        },
        alignment: {
            type: 'string',
            default: 'center',
        }
    },

    edit: ...
    save: ...
} );

Generowanie edytora

edit: function( props ) {
var focus = props.focus;
var focusedEditable = props.focus ? props.focus.editable || 'name' : null;
var alignment = props.attributes.alignment;
var attributes = props.attributes;

var onSelectImage = function( media ) {
    return props.setAttributes( {
        mediaURL: media.url,
        mediaID: media.id,
    } );
};

function onChangeAlignment( newAlignment ) {
    props.setAttributes( { alignment: newAlignment } );
}

return [
    !! focus && el( // Display controls when the block is clicked on.
        blocks.BlockControls,
        { key: 'controls' },
        el(
            blocks.AlignmentToolbar,
            {
                value: alignment,
                onChange: onChangeAlignment,
            }
        ),
    ),
    el( 'div', { className: props.className },
        el( 'div', {
                className: attributes.mediaID ? 'wpmagus-reviewer-image image-active' : 'wpmagus-reviewer-image image-inactive',
                style: attributes.mediaID ? { } : {}
            },
            el( blocks.MediaUpload, {
                onSelect: onSelectImage,
                type: 'image',
                value: attributes.mediaID,
                render: function( obj ) {
                    return el( components.Button, {
                            className: attributes.mediaID ? 'image-button' : 'button button-large',
                            onClick: obj.open
                        },
                        ! attributes.mediaID ? i18n.__( 'Upload Image' ) : el( 'img', { src: attributes.mediaURL } )
                    ); }
            } )
        ),
        el( 'div', {
                className: 'wpmagus-review-content', style: { textAlign: alignment }
            },
            el( blocks.RichText, {
                tagName: 'p',
                inline: true,
                placeholder: i18n.__( 'Write the review here...' ),
                value: attributes.review,
                onChange: function( newReview ) {
                    props.setAttributes( { review: newReview } );
                },
                focus: focusedEditable === 'review' ? focus : null,
                onFocus: function( focus ) {
                    props.setFocus( _.extend( {}, focus, { editable: 'review' } ) );
                },
            } ),
            el( blocks.RichText, {
                tagName: 'p',
                className: 'wpamgus-reviewer-name',
                inline: false,
                placeholder: i18n.__( 'Your name goes here...' ),
                value: attributes.name,
                onChange: function( newName ) {
                    props.setAttributes( { name: newName } );
                },
                focus: focusedEditable === 'name' ? focus : null,
                onFocus: function( focus ) {
                    props.setFocus( _.extend( {}, focus, { editable: 'name' } ) );
                },
            } ),
        ),
    )
];
},

Zapis do bazy

save: function( props ) {
var attributes = props.attributes;
var alignment = props.attributes.alignment;
return (
    el( 'div', { className: props.className },
        attributes.mediaURL &&
        el( 'div', { className: 'wpmagus-reviewer-image', style: {} },
            el( 'img', { src: attributes.mediaURL } ),
        ),
        el( 'div', { className: 'wpmagus-review-content', style: { textAlign: attributes.alignment } },
            attributes.review && el( 'p', {}, attributes.review ),
            el( 'p', { className: 'wpmagus-reviewer-name' }, attributes.name )
        )
    )
);
},

Ale też uważajcie

Nie zapominajcie o semantyce, bo

  • czasem trzeba wpisów poszukać (autor książki, ISBN, itp.)
  • a niektóre informacje wyświetla się w wielu miejscach

Dzięki za uwagę!

Krzysiek Dróżdż
krzysiek@wpmagus.pl
WPmagus.pl