implement Gutenberg block to add liveticker without legacy shortcode

* implement react-based JS block
* refactor shortcode and widget to use the same syntax and classes
This commit is contained in:
Stefan Kalscheuer 2019-11-23 17:54:53 +01:00
parent e201d7c02f
commit 9ddcc41c6b
11 changed files with 168 additions and 16 deletions

View File

@ -4,7 +4,8 @@
"browser": true "browser": true
}, },
"globals": { "globals": {
"sclivetickerAjax": "readonly" "sclivetickerAjax": "readonly",
"wp": "readonly"
}, },
"extends": [ "extends": [
"plugin:@wordpress/eslint-plugin/recommended", "plugin:@wordpress/eslint-plugin/recommended",
@ -16,7 +17,8 @@
"*" "*"
], ],
"rules": { "rules": {
"no-var": "off" "no-var": "off",
"object-shorthand": "off"
} }
} }
] ]

View File

@ -65,13 +65,17 @@
"phpcs --standard=phpcs.xml -s" "phpcs --standard=phpcs.xml -s"
], ],
"lint-css": [ "lint-css": [
"./node_modules/stylelint/bin/stylelint.js styles/block.css",
"./node_modules/stylelint/bin/stylelint.js styles/liveticker.css" "./node_modules/stylelint/bin/stylelint.js styles/liveticker.css"
], ],
"lint-js": [ "lint-js": [
"./node_modules/eslint/bin/eslint.js scripts/block.js",
"./node_modules/eslint/bin/eslint.js scripts/liveticker.js" "./node_modules/eslint/bin/eslint.js scripts/liveticker.js"
], ],
"minify": [ "minify": [
"minifycss styles/block.css > styles/block.min.css",
"minifycss styles/liveticker.css > styles/liveticker.min.css", "minifycss styles/liveticker.css > styles/liveticker.min.css",
"minifyjs scripts/block.js > scripts/block.min.js",
"minifyjs scripts/liveticker.js > scripts/liveticker.min.js" "minifyjs scripts/liveticker.js > scripts/liveticker.min.js"
] ]
} }

View File

@ -202,4 +202,35 @@ class SCLiveticker_Admin extends SCLiveticker {
return $result; return $result;
} }
/**
* Register custom Gutenberg block type.
*
* @return void
* @since 1.1
*/
public static function register_block() {
wp_register_script(
'scliveticker-editor',
SCLIVETICKER_BASE . 'scripts/block.min.js',
array( 'wp-blocks', 'wp-element' ),
self::VERSION,
true
);
wp_register_style(
'scliveticker-editor',
SCLIVETICKER_BASE . 'styles/block.min.css',
array(),
self::VERSION
);
register_block_type(
'scliveticker-block/liveticker',
array(
'editor_script' => 'scliveticker-editor',
'editor_style' => 'scliveticker-editor',
)
);
}
} }

View File

@ -70,7 +70,7 @@ class SCLiveticker_Widget extends WP_Widget {
echo '<ul class="sclt-widget'; echo '<ul class="sclt-widget';
if ( '1' === $ajax ) { if ( '1' === $ajax ) {
echo ' sclt-widget-ajax" ' echo ' sclt-ajax" '
. 'data-sclt-ticker="' . esc_attr( $category ) . '" ' . 'data-sclt-ticker="' . esc_attr( $category ) . '" '
. 'data-sclt-limit="' . esc_attr( $count ) . '" ' . 'data-sclt-limit="' . esc_attr( $count ) . '" '
. 'data-sclt-last="' . esc_attr( current_datetime()->getTimestamp() ); . 'data-sclt-last="' . esc_attr( current_datetime()->getTimestamp() );

View File

@ -198,14 +198,14 @@ class SCLiveticker {
$show_feed = 1 === self::$options['show_feed']; $show_feed = 1 === self::$options['show_feed'];
} }
$output = '<ul class="sclt-ticker'; $output = '<div class="wp-block-scliveticker-ticker';
if ( 1 === self::$options['enable_ajax'] ) { if ( 1 === self::$options['enable_ajax'] ) {
$output .= ' sclt-ticker-ajax" ' $output .= ' sclt-ajax" '
. 'data-sclt-ticker="' . $ticker . '" ' . 'data-sclt-ticker="' . $ticker . '" '
. 'data-sclt-limit="' . $limit . '" ' . 'data-sclt-limit="' . $limit . '" '
. 'data-sclt-last="' . current_datetime()->getTimestamp(); . 'data-sclt-last="' . current_datetime()->getTimestamp();
} }
$output .= '">'; $output .= '"><ul>';
$args = array( $args = array(
'post_type' => 'scliveticker_tick', 'post_type' => 'scliveticker_tick',
@ -226,7 +226,7 @@ class SCLiveticker {
$output .= self::tick_html( get_the_time( 'd.m.Y H.i' ), get_the_title(), get_the_content() ); $output .= self::tick_html( get_the_time( 'd.m.Y H.i' ), get_the_title(), get_the_content() );
} }
$output .= '</ul>'; $output .= '</ul></div>';
// Show RSS feed link, if configured. // Show RSS feed link, if configured.
if ( $show_feed ) { if ( $show_feed ) {

91
scripts/block.js Normal file
View File

@ -0,0 +1,91 @@
/**
* stklcode-liveticker Gutenberg Block
*
* Gutenberg Block to integrate the liveticker widget without shortcode.
*/
( function() {
var { __ } = wp.i18n;
var { registerBlockType } = wp.blocks;
var el = wp.element.createElement;
registerBlockType( 'scliveticker/ticker', {
title: __( 'Liveticker', 'stklcode-liveticker' ),
icon: 'rss',
category: 'widgets',
keywords: [
__( 'Liveticker', 'stklcode-liveticker' ),
],
attributes: {
ticker: {
type: 'string',
default: '',
},
limit: {
type: 'number',
default: 5,
},
unlimited: {
type: 'boolean',
default: false,
},
},
edit: function( props ) {
return el(
'div',
{ className: props.className + ' components-placeholder' },
[
el(
wp.components.TextControl,
{
label: [
el(
wp.components.Dashicon,
{ icon: 'rss' }
),
__( 'Liveticker', 'stklcode-liveticker' ) ],
value: props.attributes.ticker,
onChange: function( val ) {
props.setAttributes( { ticker: val } );
},
}
),
el(
wp.components.TextControl,
{
label: __( 'Number of Ticks', 'stklcode-liveticker' ),
type: 'number',
min: 1,
step: 1,
disabled: props.attributes.unlimited,
value: props.attributes.limit,
onChange: function( val ) {
props.setAttributes( { limit: val } );
},
}
),
el(
wp.components.CheckboxControl,
{
label: __( 'unlimited', 'stklcode-liveticker' ),
checked: props.attributes.unlimited,
onChange: function( val ) {
props.setAttributes( { unlimited: val } );
},
}
),
],
);
},
save: function( props ) {
return el(
'div',
{
className: props.className + ' sclt-ajax',
'data-sclt-ticker': props.attributes.ticker,
'data-sclt-limit': props.attributes.unlimited ? 0 : props.attributes.limit,
'data-sclt-last': 0,
}
);
},
} );
}() );

View File

@ -1,7 +1,7 @@
/** /**
* Contructor of the scLiveticker object. * Contructor of the scLiveticker object.
* *
* @constructor * @class
*/ */
function scLiveticker() { function scLiveticker() {
} }
@ -24,26 +24,38 @@ scLiveticker.init = function() {
// Get ticker elements. // Get ticker elements.
scLiveticker.ticker = [].map.call( scLiveticker.ticker = [].map.call(
document.querySelectorAll( 'ul.sclt-ticker-ajax' ), document.querySelectorAll( 'div.wp-block-scliveticker-ticker.sclt-ajax' ),
function( elem ) { function( elem ) {
var list = elem.querySelector( 'ul' );
if ( ! list ) {
list = document.createElement( 'ul' );
elem.appendChild( list );
}
return { return {
s: elem.getAttribute( 'data-sclt-ticker' ), s: elem.getAttribute( 'data-sclt-ticker' ),
l: elem.getAttribute( 'data-sclt-limit' ), l: elem.getAttribute( 'data-sclt-limit' ),
t: elem.getAttribute( 'data-sclt-last' ), t: elem.getAttribute( 'data-sclt-last' ),
e: elem, e: list,
}; };
} }
); );
// Get widget elements. // Get widget elements.
scLiveticker.widgets = [].map.call( scLiveticker.widgets = [].map.call(
document.querySelectorAll( 'ul.sclt-widget-ajax' ), document.querySelectorAll( 'div.wp-widget-scliveticker-ticker.sclt-ajax' ),
function( elem ) { function( elem ) {
var list = elem.querySelector( 'ul' );
if ( ! list ) {
list = document.createElement( 'ul' );
elem.appendChild( list );
}
return { return {
w: elem.getAttribute( 'data-sclt-ticker' ), w: elem.getAttribute( 'data-sclt-ticker' ),
l: elem.getAttribute( 'data-sclt-limit' ), l: elem.getAttribute( 'data-sclt-limit' ),
t: elem.getAttribute( 'data-sclt-last' ), t: elem.getAttribute( 'data-sclt-last' ),
e: elem, e: list,
}; };
} }
); );
@ -132,7 +144,7 @@ scLiveticker.update = function() {
scLiveticker.updateHTML = function( t, u ) { scLiveticker.updateHTML = function( t, u ) {
// Prepend HTML of new ticks. // Prepend HTML of new ticks.
t.e.innerHTML = u.h + t.e.innerHTML; t.e.innerHTML = u.h + t.e.innerHTML;
t.e.setAttribute( 'data-sclt-last', u.t ); t.e.parentNode.setAttribute( 'data-sclt-last', u.t );
// Remove tail, if limit is set. // Remove tail, if limit is set.
if ( 0 < t.l ) { if ( 0 < t.l ) {

View File

@ -55,6 +55,9 @@ add_shortcode( 'liveticker', array( 'SCLiveticker', 'shortcode_ticker_show' ) );
// Add Widget. // Add Widget.
add_action( 'widgets_init', array( 'SCLiveticker_Widget', 'register' ) ); add_action( 'widgets_init', array( 'SCLiveticker_Widget', 'register' ) );
// Add Gutenberg block.
add_action( 'enqueue_block_editor_assets', array( 'SCLiveticker_Admin', 'register_block' ) );
// Autoload. // Autoload.
spl_autoload_register( 'scliveticker_autoload' ); spl_autoload_register( 'scliveticker_autoload' );

7
styles/block.css Normal file
View File

@ -0,0 +1,7 @@
div.wp-block-scliveticker-ticker div.components-base-control:first-child label {
font-weight: 600;
}
div.wp-block-scliveticker-ticker div.components-base-control:first-child label > .dashicon {
margin-right: 8px;
}

View File

@ -1,8 +1,10 @@
ul.sclt-ticker { div.wp-block-scliveticker-ticker ul,
div.wp-block-scliveticker-ajax-ticker ul {
list-style-type: none; list-style-type: none;
} }
ul.sclt-ticker > li.sclt-tick { div.wp-block-scliveticker-ticker ul > li.sclt-tick,
div.wp-block-scliveticker-ajax-ticker ul > li.sclt-tick {
background-color: #f5f5f5; background-color: #f5f5f5;
list-style-type: none; list-style-type: none;
margin: 0.1em; margin: 0.1em;

View File

@ -40,7 +40,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr> </tr>
<tr> <tr>
<td> <td>
<label for="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>"><?php esc_html_e( 'Number of Ticks:', 'stklcode-liveticker' ); ?></label> <label for="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>"><?php esc_html_e( 'Number of Ticks', 'stklcode-liveticker' ); ?>:</label>
</td> </td>
<td> <td>
<select id="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'count' ) ); ?>"> <select id="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'count' ) ); ?>">