diff --git a/includes/blocks/class-displayfeaturedimagegenesis-blocks.php b/includes/blocks/class-displayfeaturedimagegenesis-blocks.php new file mode 100644 index 0000000..5d0b5ac --- /dev/null +++ b/includes/blocks/class-displayfeaturedimagegenesis-blocks.php @@ -0,0 +1,257 @@ +register_script_style(); + foreach ( $this->blocks() as $block => $data ) { + if ( 'term' === $block ) { + continue; + } + register_block_type( + "display-featured-image-genesis/{$block}", + array( + 'editor_script' => 'displayfeaturedimagegenesis-block', + 'attributes' => $this->get_attributes( $block ), + 'render_callback' => array( $this, 'render' ), + ) + ); + } + add_action( 'enqueue_block_editor_assets', array( $this, 'localize' ) ); + } + + /** + * Register the block script and style. + */ + public function register_script_style() { + $version = displayfeaturedimagegenesis_get()->version; + $minify = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : ' . min'; + if ( ! $minify ) { + $version .= current_time( 'gmt' ); + } + wp_register_script( + 'displayfeaturedimagegenesis-block', + plugin_dir_url( dirname( __FILE__ ) ) . "js/block{$minify}.js", + array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-editor' ), + $version, + false + ); + } + + /** + * Get the list of blocks to create. + * @return array + */ + private function blocks() { + return array( + 'term' => array( + 'title' => __( 'Display Featured Term Image', 'display-featured-image-genesis' ), + 'description' => __( 'Display a featured term', 'display-featured-image-genesis' ), + 'keywords' => array( + __( 'Term', 'display-featured-image-genesis' ), + __( 'Featured Image', 'display-featured-image-genesis' ), + ), + ), + 'author' => array( + 'title' => __( 'Display Featured Author Profile', 'display-featured-image-genesis' ), + 'description' => __( 'Display a featured author', 'display-featured-image-genesis' ), + 'keywords' => array( + __( 'Author', 'display-featured-image-genesis' ), + __( 'Featured Image', 'display-featured-image-genesis' ), + ), + ), + 'post-type' => array( + 'title' => __( 'Display Featured Post Type Archive Image', 'display-featured-image-genesis' ), + 'description' => __( 'Display a featured content type', 'display-featured-image-genesis' ), + 'keywords' => array( + __( 'Post Type', 'display-featured-image-genesis' ), + __( 'Featured Image', 'display-featured-image-genesis' ), + ), + ), + ); + } + + /** + * Render the widget in a container div. + * + * @param $attributes + * + * @return string + */ + public function render( $attributes ) { + rgc_error_log( $attributes ); +// $classes = $this->get_block_classes( $attributes ); +// $output = '
'; +//// $output .= $this->register->shortcode( $attributes ); +// $output .= '
'; + + return 'this is the output'; + } + + /** + * Get the block classes. + * + * @param $attributes + * + * @return array + * @since 0.4.0 + */ + private function get_block_classes( $attributes ) { + $classes = array( + 'wp-block-displayfeaturedimagegenesis' . 'term', + ); + if ( ! empty( $attributes['className'] ) ) { + $classes[] = $attributes['className']; + } + if ( ! empty( $attributes['blockAlignment'] ) ) { + $classes[] = 'align' . $attributes['blockAlignment']; + } + + return $classes; + } + + /** + * @param $block + * + * @return array + */ + protected function get_attributes( $block ) { + $attributes = array_merge( + $this->fields(), + $this->get_block_fields( $block ) + ); + foreach ( $attributes as $key => $value ) { + $attributes[ $key ] = $this->get_individual_field_attributes( $value, $key ); + } + + return $attributes; + } + + /** + * + */ + public function localize() { + $args = array(); + foreach ( $this->blocks() as $block => $data ) { + $args['blocks'][ $block ] = $this->get_localization_data( $block, $data ); + } + wp_localize_script( 'displayfeaturedimagegenesis-block', 'DisplayFeaturedImageGenesisBlock', $args ); + } + + /** + * Get the data for localizing everything. + * @return array + */ + protected function get_localization_data( $block, $data ) { + return array( + 'block' => "displayfeaturedimagegenesis/{$block}", + 'title' => $data['title'], + 'description' => $data['description'], + 'keywords' => $data['keywords'], + 'panels' => array( + 'main' => array( + 'title' => __( 'Block Settings', 'display-featured-image-genesis' ), + 'initialOpen' => true, + 'attributes' => $this->get_attributes( $block ), + ), + ), + 'icon' => 'format-image', + 'category' => 'widgets', + ); + } + + /** + * @return array + */ + private function fields() { + return array( + 'blockAlignment' => array( + 'type' => 'string', + 'default' => '', + ), + 'className' => array( + 'type' => 'string', + 'default' => '', + ), + 'title' => array( + 'type' => 'string', + 'default' => '', + 'label' => __( 'Title', 'display-featured-image-genesis' ), + ), + 'show_image' => array( + 'type' => 'boolean', + 'default' => 1, + 'label' => __( 'Show Featured Image', 'display-featured-image-genesis' ), + 'method' => 'checkbox', + ), + 'image_size' => array( + 'type' => 'string', + 'default' => 'medium', + 'label' => __( 'Image Size:', 'display-featured-image-genesis' ), + 'method' => 'select', + 'choices' => $this->get_image_size(), + ), + ); + } + + /** + * Get an array of attributes for an individual field. + * + * @param $field + * @param $id + * + * @return array + */ + protected function get_individual_field_attributes( $field, $id ) { + $field_type = $field['type']; + if ( empty( $field['label'] ) ) { + return $field; + } + $attributes = array( + 'type' => $field['type'], + 'default' => $field['default'], + 'label' => $field['label'], + 'method' => empty( $field['method'] ) ? 'text' : $field['method'], + ); + if ( in_array( 'number', array( $field_type, $attributes['method'] ), true ) ) { + $attributes['min'] = $field['args']['min']; + $attributes['max'] = $field['args']['max']; + } elseif ( 'select' === $attributes['method'] ) { + foreach ( $field['choices'] as $value => $label ) { + $attributes['options'][] = array( + 'value' => $value, + 'label' => $label, + ); + } + } elseif ( 'boolean' === $field_type ) { + $attributes['default'] = 0; + } + + return $attributes; + } + + private function get_image_size() { + $sizes = genesis_get_image_sizes(); + $options = array(); + foreach ( (array) $sizes as $name => $size ) { + $options[ $name ] = sprintf( '%s ( %s x %s )', esc_html( $name ), (int) $size['width'], (int) $size['height'] ); + } + + return $options; + } + + /** + * @param $block + * + * @return array + */ + private function get_block_fields( $block ) { + return array(); + } +} diff --git a/includes/class-displayfeaturedimagegenesis.php b/includes/class-displayfeaturedimagegenesis.php index 1a7c1a5..82fb952 100644 --- a/includes/class-displayfeaturedimagegenesis.php +++ b/includes/class-displayfeaturedimagegenesis.php @@ -125,6 +125,7 @@ class Display_Featured_Image_Genesis { add_action( 'widgets_init', array( $this->widgets, 'register_widgets' ) ); add_action( 'widgets_init', array( $this->widgets, 'register_shortcodes' ) ); add_action( 'admin_enqueue_scripts', array( $this->widgets, 'enqueue_scripts' ) ); + add_action( 'init', array( $this, 'maybe_register_block' ) ); // Taxonomies, Authors add_filter( 'displayfeaturedimagegenesis_get_taxonomies', array( $this->taxonomies, 'remove_post_status_terms' ) ); @@ -249,6 +250,15 @@ class Display_Featured_Image_Genesis { } } + public function maybe_register_block() { + if ( ! function_exists( 'register_block_type' ) ) { + return; + } + include_once 'blocks/class-displayfeaturedimagegenesis-blocks.php'; + $blocks = new DisplayFeaturedImageGenesisBlocks(); + $blocks->init(); + } + /** * Add link to plugin settings page in plugin table * @param $links array link to settings page diff --git a/includes/js/block.js b/includes/js/block.js new file mode 100644 index 0000000..43e2a5c --- /dev/null +++ b/includes/js/block.js @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2019 Robin Cornett + */ + +(function ( wp, undefined ) { + 'use strict'; + const DisplayFeaturedImageBlockObject = { + el: wp.element.createElement, + }; + + /** + * Initialize and register the block. + */ + DisplayFeaturedImageBlockObject.init = function () { + const registerBlockType = wp.blocks.registerBlockType, + ServerSideRender = wp.components.ServerSideRender, + InspectorControls = wp.blockEditor.InspectorControls; + Object.keys( DisplayFeaturedImageBlockObject.params.blocks ).forEach( function ( key, index ) { + if ( DisplayFeaturedImageBlockObject.params.blocks.hasOwnProperty( key ) ) { + const data = DisplayFeaturedImageBlockObject.params.blocks[key]; + registerBlockType( data.block, { + title: data.title, + description: data.description, + keywords: data.keywords, + icon: data.icon, + category: data.category, + supports: { + html: false + }, + + getEditWrapperProps( {blockAlignment} ) { + return {'data-align': blockAlignment}; + }, + + edit: props => { + const { + attributes, + setAttributes + } = props, + Fragment = wp.element.Fragment, + BlockControls = wp.blockEditor.BlockControls, + BlockAlignmentToolbar = wp.blockEditor.BlockAlignmentToolbar; + return [ + DisplayFeaturedImageBlockObject.el( ServerSideRender, { + block: data.block, + attributes: attributes + } ), + DisplayFeaturedImageBlockObject.el( Fragment, null, + DisplayFeaturedImageBlockObject.el( BlockControls, null, + DisplayFeaturedImageBlockObject.el( BlockAlignmentToolbar, { + value: attributes.blockAlignment, + controls: ['wide', 'full'], + onChange: ( value ) => { + setAttributes( {blockAlignment: value} ); + }, + } ) + ), + ), + DisplayFeaturedImageBlockObject.el( InspectorControls, {}, + _getPanels( props ) + ) + ]; + }, + + save: props => { + return null; + }, + } ); + } + } ); + }; + + /** + * Get the panels for the block controls. + * + * @param props + * @return {Array} + * @private + */ + function _getPanels( props ) { + const panels = [], + PanelBody = wp.components.PanelBody; + Object.keys( DisplayFeaturedImageBlockObject.params.blocks ).forEach( function ( block_key, index ) { + if ( DisplayFeaturedImageBlockObject.params.blocks.hasOwnProperty( block_key ) ) { + const data = DisplayFeaturedImageBlockObject.params.blocks[ block_key ]; + Object.keys( data.panels ).forEach( function ( key, index ) { + if ( data.panels.hasOwnProperty( key ) ) { + const IndividualPanel = data.panels[key]; + panels[index] = DisplayFeaturedImageBlockObject.el( PanelBody, { + title: IndividualPanel.title, + initialOpen: IndividualPanel.initialOpen, + className: 'display-featured-image-panel-' + key + }, _getControls( props, IndividualPanel.attributes ) ); + } + } ); + } + } ); + + return panels; + } + + /** + * Get all of the block controls, with defaults and options. + * + * @param props + * @param fields + * @return {Array} + * @private + */ + function _getControls( props, fields ) { + const controls = []; + Object.keys( fields ).forEach( function ( key, index ) { + if ( fields.hasOwnProperty( key ) ) { + var skipped = [ 'blockAlignment', 'className' ]; + if ( -1 !== skipped.indexOf( key ) ) { + return; + } + const IndividualField = fields[key], + control = _getControlType( IndividualField.method, IndividualField.type ); + controls[index] = DisplayFeaturedImageBlockObject.el( control, _getIndividualControl( key, IndividualField, props ) ); + } + } ); + + return controls; + } + + /** + * Get the control type. + * @param method + * @param control_type + * @return {*} + * @private + */ + function _getControlType( method, control_type ) { + const { + TextControl, + SelectControl, + RangeControl, + CheckboxControl, + TextareaControl + } = wp.components; + const control = TextControl; + if ( 'select' === method ) { + return SelectControl; + } else if ( 'number' === method && 'number' === control_type ) { + return RangeControl; + } else if ( 'checkbox' === method ) { + return CheckboxControl; + } else if ( 'textarea' === method ) { + return TextareaControl; + } + + return control; + } + + /** + * Build the individual control object. Sets up standard properties for all + * controls; then adds custom properties as needed. + * + * @param key + * @param field + * @param props + * @return {{label: *, value: *, className: string, onChange: onChange}} + * @private + */ + function _getIndividualControl( key, field, props ) { + const {attributes, setAttributes} = props; + const control = { + heading: field.heading, + label: field.label, + value: attributes[key], + className: 'displayfeaturedimagegenesis-' + key, + onChange: ( value ) => { + setAttributes( {[key]: value} ); + } + }; + + if ( 'select' === field.method ) { + control.options = field.options; + } else if ( 'number' === field.method ) { + control.min = field.min; + control.max = field.max; + if ( 'number' !== field.type ) { + control.type = 'number'; + } else { + control.initialPosition = field.min; + } + } else if ( 'checkbox' === field.method ) { + control.checked = attributes[key]; + } + + return control; + } + + DisplayFeaturedImageBlockObject.params = typeof DisplayFeaturedImageGenesisBlock === 'undefined' ? '' : DisplayFeaturedImageGenesisBlock; + + if ( typeof DisplayFeaturedImageBlockObject.params !== 'undefined' ) { + DisplayFeaturedImageBlockObject.init(); + } +} )( wp );