From e365bacaa1eaf00f626e44d378139762008997e8 Mon Sep 17 00:00:00 2001 From: Jonathan Bardo Date: Fri, 24 Feb 2017 10:09:50 -0500 Subject: [PATCH 01/19] Port over paint kit hero widget --- assets/js/widgets/hero-admin.js | 174 ++++++++++ assets/js/widgets/hero-admin.min.js | 1 + functions.php | 44 +++ inc/widgets/class-base-widget.php | 479 ++++++++++++++++++++++++++++ inc/widgets/class-hero.php | 245 ++++++++++++++ 5 files changed, 943 insertions(+) create mode 100755 assets/js/widgets/hero-admin.js create mode 100644 assets/js/widgets/hero-admin.min.js create mode 100755 inc/widgets/class-base-widget.php create mode 100755 inc/widgets/class-hero.php diff --git a/assets/js/widgets/hero-admin.js b/assets/js/widgets/hero-admin.js new file mode 100755 index 00000000..9e5466e1 --- /dev/null +++ b/assets/js/widgets/hero-admin.js @@ -0,0 +1,174 @@ +/* global jQuery, primer_widgets_hero_admin */ + +(function( $ ) { + + var link = { + + init: function( input ) { + + if ( ! ( $ && $.ui && $.ui.autocomplete ) ) { + + return; + + } + + var $input = $( input ), + cache, last; + + $input.on( 'keydown', function() { + + $input.removeAttr( 'aria-activedescendant' ); + + } ) + .autocomplete( { + + source: function( request, response ) { + + if ( last === request.term ) { + + response( cache ); + + return; + + } + + if ( /^https?:/.test( request.term ) || request.term.indexOf( '.' ) !== -1 ) { + + return response(); + + } + + $.post( + window.ajaxurl, + { + action: 'wp-link-ajax', + page: 1, + search: request.term, + _ajax_linking_nonce: primer_widgets_hero_admin._ajax_linking_nonce + }, + function( data ) { + + cache = data; + response( data ); + + }, + 'json' + ); + + last = request.term; + + }, + focus: function( event, ui ) { + + $input.attr( 'aria-activedescendant', 'mce-wp-autocomplete-' + ui.item.ID ); + + /* + * Don't empty the URL input field, when using the arrow keys to + * highlight items. See api.jqueryui.com/autocomplete/#event-focus + */ + event.preventDefault(); + + }, + select: function( event, ui ) { + + $input.val( ui.item.permalink ); + + // This is for the customizer + $input.trigger( 'change' ); + + return false; + + }, + open: function() { + + $input.attr( 'aria-expanded', 'true' ); + + }, + close: function() { + + $input.attr( 'aria-expanded', 'false' ); + + }, + minLength: 2, + position: { + + my: 'left top+2' + + } + + } ).autocomplete( 'instance' )._renderItem = function( ul, item ) { + + return $( '
  • ' ) + .append( '' + item.title + ' ' + item.info + '' ) + .appendTo( ul ); + + }; + + $input.attr( { + 'role': 'combobox', + 'aria-autocomplete': 'list', + 'aria-expanded': 'false', + 'aria-owns': $input.autocomplete( 'widget' ).attr( 'id' ) + } ) + .on( 'focus', function() { + + var inputValue = $input.val(); + + /* + * Don't trigger a search if the URL field already has a link or is empty. + * Also, avoids screen readers announce `No search results`. + */ + if ( inputValue && ! /^https?:/.test( inputValue ) ) { + + $input.autocomplete( 'search' ); + + } + + } ) + // Returns a jQuery object containing the menu element. + .autocomplete( 'widget' ) + .css( + { + 'z-index': 9999999 + } + ) + .attr( 'role', 'listbox' ) + .removeAttr( 'tabindex' ) // Remove the `tabindex=0` attribute added by jQuery UI. + /* + * Looks like Safari and VoiceOver need an `aria-selected` attribute. See ticket #33301. + * The `menufocus` and `menublur` events are the same events used to add and remove + * the `ui-state-focus` CSS class on the menu items. See jQuery UI Menu Widget. + */ + .on( 'menufocus', function( event, ui ) { + + ui.item.attr( 'aria-selected', 'true' ); + + }) + .on( 'menublur', function() { + + /* + * The `menublur` event returns an object where the item is `null` + * so we need to find the active item with other means. + */ + $( this ).find( '[aria-selected="true"]' ).removeAttr( 'aria-selected' ); + + }); + + } // end init + + }; + + function addAutocomplete() { + + $( '.primer-widget-hero input.link' ).each( function() { + + link.init( this ); + + } ); + + } + + $( document ).ready( addAutocomplete ); + $( document ).on( 'primer.widgets.change', addAutocomplete ); + +})( jQuery ); diff --git a/assets/js/widgets/hero-admin.min.js b/assets/js/widgets/hero-admin.min.js new file mode 100644 index 00000000..f0ba7f8f --- /dev/null +++ b/assets/js/widgets/hero-admin.min.js @@ -0,0 +1 @@ +!function(a){function b(){a(".primer-widget-hero input.link").each(function(){c.init(this)})}var c={init:function(b){if(a&&a.ui&&a.ui.autocomplete){var c,d,e=a(b);e.on("keydown",function(){e.removeAttr("aria-activedescendant")}).autocomplete({source:function(b,e){return d===b.term?void e(c):/^https?:/.test(b.term)||b.term.indexOf(".")!==-1?e():(a.post(window.ajaxurl,{action:"wp-link-ajax",page:1,search:b.term,_ajax_linking_nonce:primer_widgets_hero_admin._ajax_linking_nonce},function(a){c=a,e(a)},"json"),void(d=b.term))},focus:function(a,b){e.attr("aria-activedescendant","mce-wp-autocomplete-"+b.item.ID),a.preventDefault()},select:function(a,b){return e.val(b.item.permalink),e.trigger("change"),!1},open:function(){e.attr("aria-expanded","true")},close:function(){e.attr("aria-expanded","false")},minLength:2,position:{my:"left top+2"}}).autocomplete("instance")._renderItem=function(b,c){return a('
  • ').append(""+c.title+' '+c.info+"").appendTo(b)},e.attr({role:"combobox","aria-autocomplete":"list","aria-expanded":"false","aria-owns":e.autocomplete("widget").attr("id")}).on("focus",function(){var a=e.val();a&&!/^https?:/.test(a)&&e.autocomplete("search")}).autocomplete("widget").css({"z-index":9999999}).attr("role","listbox").removeAttr("tabindex").on("menufocus",function(a,b){b.item.attr("aria-selected","true")}).on("menublur",function(){a(this).find('[aria-selected="true"]').removeAttr("aria-selected")})}}};a(document).ready(b),a(document).on("primer.widgets.change",b)}(jQuery); \ No newline at end of file diff --git a/functions.php b/functions.php index 3cde142b..f39ef288 100755 --- a/functions.php +++ b/functions.php @@ -102,6 +102,13 @@ */ require_once get_template_directory() . '/inc/hooks.php'; +/** + * Load Primer widget base class + * + * @since NEXT + */ +require_once get_template_directory() . '/inc/widgets/class-base-widget.php'; + /** * Load Beaver Builder compatibility file. * @@ -436,6 +443,43 @@ function primer_register_sidebars() { } add_action( 'widgets_init', 'primer_register_sidebars' ); +/** + * Register custom Primer widgets. + * + * @link http://codex.wordpress.org/Function_Reference/register_widget + * @since NEXT + */ +function primer_register_widgets() { + + /** + * Filter registered custom widgets class name and their path. + * + * @since NEXT + * + * @var array + */ + $widgets = apply_filters( 'primer_widgets', + array( + 'Primer_Hero' => get_template_directory() . '/inc/widgets/class-hero.php' + ) + ); + + foreach ( $widgets as $widget_class => $filepath ) { + + if ( file_exists( $filepath ) ) { + + require_once $filepath; + + register_widget( $widget_class ); + + } + + } + + +} +add_action( 'widgets_init', 'primer_register_widgets' ); + /** * Enqueue theme scripts and styles. * diff --git a/inc/widgets/class-base-widget.php b/inc/widgets/class-base-widget.php new file mode 100755 index 00000000..f574f564 --- /dev/null +++ b/inc/widgets/class-base-widget.php @@ -0,0 +1,479 @@ + '', + 'icon' => '', + 'class' => 'widefat', + 'id' => '', + 'name' => '', + 'label' => '', + 'label_after' => false, + 'description' => '', + 'type' => 'text', + 'sanitizer' => 'sanitize_text_field', + 'escaper' => 'esc_html', + 'form_callback' => 'render_form_input', + 'default' => '', // If you need a default value + 'value' => '', + 'placeholder' => '', + 'sortable' => true, + 'atts' => '', // Input attributes + 'show_front_end' => true, // Are we showing this field on the front end? + 'show_empty' => false, // Show the field even if value is empty + 'select_options' => [], // Only used if type=select & form_callback=render_form_select + ]; + + /** + * Widget base constructor + * + * @param string $id_base + * @param string $name + * @param array $widget_options + */ + public function __construct( $id_base, $name, array $widget_options ) { + + parent::__construct( $id_base, $name, $widget_options ); + + } + + /** + * Add common ressources needed for the form + * + * @param array $instance + * + * @return string|void + */ + public function form( $instance ) { + + add_action( 'admin_footer', [ $this, 'enqueue_scripts' ] ); + add_action( 'customize_controls_print_footer_scripts', [ $this, 'print_customizer_scripts' ] ); + + ?> + + get_fields( $old_instance ); + + // Force value for checkbox since they are not posted + foreach ( $fields as $key => $field ) { + + if ( 'checkbox' === $field['type'] && ! isset( $new_instance[ $key ]['value'] ) ) { + + $new_instance[ $key ] = [ 'value' => 'no' ]; + + } + + } + + // Starting at 1 since title order is 0 + $order = 1; + + foreach ( $new_instance as $key => &$instance ) { + + $sanitizer_callback = $fields[ $key ]['sanitizer']; + + // Title can't be an array + if ( 'title' === $key ) { + + $instance = $sanitizer_callback( $instance['value'] ); + + continue; + + } + + $instance['value'] = $sanitizer_callback( $instance['value'] ); + $instance['order'] = $order++; + + } + + return $new_instance; + + } + + /** + * Initialize fields for use on front-end of forms + * + * @param array $instance + * @param array $fields (optional) + * @param bool $ordered (optional) + * + * @return array + */ + protected function get_fields( array $instance, array $fields = [], $ordered = true ) { + + $order = 0; + + foreach ( $fields as $key => &$field ) { + + $common_properties = [ + 'key' => $key, + 'icon' => $key, + 'order' => ! empty( $instance[ $key ]['order'] ) ? absint( $instance[ $key ]['order'] ) : $order, + 'id' => $this->get_field_id( $key ), + 'name' => $this->get_field_name( $key ) . '[value]', + 'value' => ! empty( $instance[ $key ]['value'] ) ? $instance[ $key ]['value'] : '', + ]; + + $common_properties = wp_parse_args( $common_properties, $this->field_defaults ); + $field = wp_parse_args( $field, $common_properties ); + + $default_closure = function( $value ) { return $value; }; + + foreach ( [ 'escaper', 'sanitizer' ] as $key ) { + + $field[ $key ] = ! is_callable( $field[ $key ] ) ? $default_closure : $field[ $key ]; + + } + + $order++; + + } + + if ( $ordered ) { + + $fields = $this->order_field( $fields ); + + } + + return $fields; + + } + + /** + * Order array by field order + * + * @param array $fields + * + * @return array + */ + protected function order_field( array $fields ) { + + uksort( $fields, function( $a, $b ) use ( $fields ) { + + // We want title first and order of non sortable fields doesn't matter + if ( ! $fields[ $a ]['sortable'] && 'title' !== $a ) { + + return 1; + + } + + return ( $fields[ $a ]['order'] < $fields[ $b ]['order'] ) ? -1 : 1; + + } ); + + return $fields; + + } + + /** + * Check if all the fields we show on the front-end are empty + * + * @param array $fields + * + * @return bool + */ + protected function is_widget_empty( array $fields ) { + + foreach ( $fields as $key => $field ) { + + /** + * Filter to ignore the title when checking if a widget is empty + * + * @since NEXT + * + * @var bool + */ + $ignore_title = (bool) apply_filters( 'primer_is_widget_empty_ignore_title', false ); + + if ( 'title' === $key && $ignore_title ) { + + continue; + + } + + if ( ! empty( $field['value'] ) && $field['show_front_end'] ) { + + return false; + + } + + } + + return true; + + } + + /** + * Print current label + * + * @param array $field + */ + protected function print_label( array $field ) { + + printf( + ' ', + esc_attr( $field['id'] ), + esc_attr( $field['description'] ), + esc_html( $field['label'] ) + ); + + } + + /** + * Print label and wrapper + * @param array $field + */ + protected function before_form_field( array $field ) { + + $classes = [ $field['type'], $field['key'] ]; + + if ( ! $field['sortable'] ) { + + $classes[] = 'not-sortable'; + + } + + if ( $field['label_after'] ) { + + $classes[] = 'label-after'; + + } + + printf( + '

    ', + implode( ' ', $classes ) + ); + + if ( ! $field['label_after'] ) { + + $this->print_label( $field ); + + } + + if ( $field['sortable'] ) { + + echo ''; + + } + + } + + /** + * Render input field for admin form + * + * @param array $field + */ + protected function render_form_input( array $field ) { + + $this->before_form_field( $field ); + + printf( + '', + esc_attr( $field['class'] ), + esc_attr( $field['id'] ), + esc_attr( $field['name'] ), + esc_attr( $field['type'] ), + esc_attr( $field['value'] ), + esc_attr( $field['placeholder'] ), + esc_attr( $field['atts'] ) + ); + + if ( $field['label_after'] ) { + + $this->print_label( $field ); + + } + + $this->after_form_field( $field ); + + } + + /** + * Render select field + * + * @param array $field + */ + protected function render_form_select( array $field ) { + + $this->before_form_field( $field ); + + printf( + ''; + + if ( $field['label_after'] ) { + + $this->print_label( $field ); + + } + + $this->after_form_field( $field ); + + } + + /** + * Render textarea field for admin widget form + * + * @param array $field + */ + protected function render_form_textarea( array $field ) { + + $this->before_form_field( $field ); + + printf( + '', + esc_attr( $field['class'] ), + esc_attr( $field['id'] ), + esc_attr( $field['name'] ), + esc_attr( $field['placeholder'] ), + esc_textarea( $field['value'] ) + ); + + $this->after_form_field( $field ); + + } + + /** + * Close wrapper of form field + * + * @param array $field + */ + protected function after_form_field( array $field ) { + + if ( $field['sortable'] ) { + + echo ''; + + } + + echo '

    '; + + } + + /** + * Print beginning of front-end display + * + * @param array $args + * @param array $fields + */ + protected function before_widget( array $args, array &$fields ) { + + $title = array_shift( $fields ); + + echo $args['before_widget']; + + if ( ! empty( $title['value'] ) ) { + + /** + * Filter the widget title + * + * @since NEXT + * + * @var string + */ + $title = (string) apply_filters( 'widget_title', $title['value'] ); + + echo $args['before_title'] . $title . $args['after_title']; + + } + + } + + /** + * Print end of front-end display + * + * @param array $args + * @param array $fields + */ + protected function after_widget( array $args, array &$fields ) { + + echo $args['after_widget']; + + } + + /** + * Helper to output only 'checked' and not checked='checked' + * IE 9 & 10 don't support the latter + * + * @param mixed $helper One of the values to compare + * @param mixed $current (true) The other value to compare if not just true + * @param bool $echo Whether to echo or just return the string + * @return string html attribute or empty string + */ + public function checked( $helper, $current, $echo = false ) { + + $result = (string) $helper === (string) $current ? 'checked' : ''; + + if ( $echo ) { + + echo $result; + + } + + return $result; + + } + + /** + * Print footer script and styles + */ + public function enqueue_scripts() {} + + /** + * Print customizer script + */ + public function print_customizer_scripts() { + + $this->enqueue_scripts(); + + } + +} diff --git a/inc/widgets/class-hero.php b/inc/widgets/class-hero.php new file mode 100755 index 00000000..6257d3d1 --- /dev/null +++ b/inc/widgets/class-hero.php @@ -0,0 +1,245 @@ + 'primer-widgets primer-widget-hero widget_text', + 'description' => __( 'A specialy crafted widget to be used in the hero section of Primer related themes.', 'primer' ), + 'customize_selective_refresh' => true, + ); + + parent::__construct( + 'primer_hero', + __( 'Homepage Hero Widget', 'primer' ), + $widget_options + ); + + } + + /** + * Widget form fields + * + * @param array $instance The widget options + * + * @return string|void + */ + public function form( $instance ) { + + parent::form( $instance ); + + $fields = $this->get_fields( $instance ); + + echo '
    '; + + echo '
    '; + + // Title field + $this->render_form_input( array_shift( $fields ) ); + + echo '
    '; + + echo '
    '; + + foreach ( $fields as $key => $field ) { + + $method = $field['form_callback']; + + if ( is_callable( array( $this, $method ) ) ) { + + $this->$method( $field ); + + } + + } + + echo '
    '; // End form + + echo '
    '; // End primer-widget-contact + + } + + /** + * Front-end display + * + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + + $fields = $this->get_fields( $instance ); + + if ( $this->is_widget_empty( $fields ) ) { + + return; + + } + + $this->before_widget( $args, $fields ); + + echo '
    '; + + foreach ( $fields as $key => $field ) { + + if ( empty( $field['value'] ) || ! $field['show_front_end'] ) { + + continue; + + } + + $escape_callback = $field['escaper']; + + if ( 'button_text' === $key ) { + + if ( ! isset( $fields['button_link'] ) || empty( $fields['button_link']['value'] ) ) { + + continue; + + } + + $link_escaper = $fields['button_link']['escaper']; + + /** + * Filter that let's someone change css class of the link generated by the widget + * + * @filter primer_widget_hero_link_class + * + * @since NEXT + */ + $class = apply_filters( 'primer_widget_hero_link_class', [ 'button' ] ); + + printf( + '

    %3$s

    ', + $link_escaper( $fields['button_link']['value'] ), + esc_attr( implode( ' ', $class ) ), + $escape_callback( $field['value'] ) + ); + + continue; + + } + + echo $escape_callback( $field['value'] );// xss ok + + } + + $this->after_widget( $args, $fields ); + + echo '
    '; // End div.textwidget + + } + + /** + * Initialize fields for use on front-end of forms + * + * @param array $instance + * @param array $fields + * @param bool $ordered + * + * @return array + */ + protected function get_fields( array $instance, array $fields = [], $ordered = false ) { + + $fields = [ + 'title' => [ + 'label' => __( 'Title:', 'primer' ), + 'description' => __( 'The title of widget. Leave empty for no title.', 'primer' ), + 'value' => ! empty( $instance['title'] ) ? $instance['title'] : '', + 'sortable' => false, + ], + 'message' => [ + 'label' => __( 'Message:', 'primer' ), + 'type' => 'textarea', + 'sanitizer' => function( $value ) { + return current_user_can( 'unfiltered_html' ) ? $value : wp_kses_post( stripslashes( $value ) ); + }, + 'escaper' => function( $value ) use ( $instance ) { + return wpautop( apply_filters( 'widget_text', $value, $instance, $this ) ); + }, + 'form_callback' => 'render_form_textarea', + 'sortable' => false, + ], + 'button_text' => [ + 'label' => __( 'Button Text:', 'primer' ), + 'type' => 'text', + 'sortable' => false, + ], + 'button_link' => [ + 'label' => __( 'Button Link URL:', 'primer' ), + 'placeholder' => __( 'Paste URL or type to search', 'primer' ), + 'type' => 'text', + 'class' => 'widefat link', + 'sanitizer' => 'esc_url_raw', + 'escaper' => 'esc_url', + 'sortable' => false, + 'show_front_end' => false, + ], + ]; + + /** + * Register custom fields for the hero widgets + * + * @since NEXT + * + * @var array $fields + * @var object $instance + */ + $fields = apply_filters( 'primer_widget_hero_custom_fields', $fields, $instance ); + $fields = parent::get_fields( $instance, $fields, $ordered ); + + /** + * Filter the hero widget fields + * + * @since NEXT + * + * @var array $fields + * @var object $instance + */ + return (array) apply_filters( 'primer_widget_hero_fields', $fields, $instance ); + + } + + /** + * Print footer script and styles + */ + public function enqueue_scripts() { + + $suffix = SCRIPT_DEBUG ? '' : '.min'; + + wp_enqueue_script( 'jquery-ui-autocomplete' ); + + wp_enqueue_script( 'primer-widgets-hero-admin', get_template_directory_uri() . "/assets/js/widgets/hero-admin{$suffix}.js", [ 'jquery', 'jquery-ui-autocomplete' ], PRIMER_VERSION, true ); + + // We need the internal linking token + wp_localize_script( + 'primer-widgets-hero-admin', + 'primer_widgets_hero_admin', + [ + '_ajax_linking_nonce' => wp_create_nonce( 'internal-linking' ), + ] + ); + + } + + /** + * Print customizer script + */ + public function print_customizer_scripts() { + + $this->enqueue_scripts(); + + wp_print_scripts( 'primer-widgets-hero-admin' ); + + } + +} From 03e0c7f523e56aedc9dbfd659c75e949ba429949 Mon Sep 17 00:00:00 2001 From: Jonathan Bardo Date: Fri, 24 Feb 2017 10:13:05 -0500 Subject: [PATCH 02/19] Fix spacing --- assets/js/widgets/hero-admin.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/js/widgets/hero-admin.js b/assets/js/widgets/hero-admin.js index 9e5466e1..d19bc5f3 100755 --- a/assets/js/widgets/hero-admin.js +++ b/assets/js/widgets/hero-admin.js @@ -128,9 +128,9 @@ // Returns a jQuery object containing the menu element. .autocomplete( 'widget' ) .css( - { - 'z-index': 9999999 - } + { + 'z-index': 9999999 + } ) .attr( 'role', 'listbox' ) .removeAttr( 'tabindex' ) // Remove the `tabindex=0` attribute added by jQuery UI. @@ -141,7 +141,7 @@ */ .on( 'menufocus', function( event, ui ) { - ui.item.attr( 'aria-selected', 'true' ); + ui.item.attr( 'aria-selected', 'true' ); }) .on( 'menublur', function() { From c71ecda8a43a380a3c251ad6e490ebbd77707b82 Mon Sep 17 00:00:00 2001 From: Jonathan Bardo Date: Fri, 24 Feb 2017 10:18:07 -0500 Subject: [PATCH 03/19] Convert array syntax to be compatible with php 5.2 --- inc/widgets/class-base-widget.php | 20 ++++++++++---------- inc/widgets/class-hero.php | 28 ++++++++++++++-------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/inc/widgets/class-base-widget.php b/inc/widgets/class-base-widget.php index f574f564..986cf4fb 100755 --- a/inc/widgets/class-base-widget.php +++ b/inc/widgets/class-base-widget.php @@ -13,7 +13,7 @@ abstract class Primer_Base_Widget extends WP_Widget { * * @var array */ - protected $field_defaults = [ + protected $field_defaults = array( 'key' => '', 'icon' => '', 'class' => 'widefat', @@ -33,8 +33,8 @@ abstract class Primer_Base_Widget extends WP_Widget { 'atts' => '', // Input attributes 'show_front_end' => true, // Are we showing this field on the front end? 'show_empty' => false, // Show the field even if value is empty - 'select_options' => [], // Only used if type=select & form_callback=render_form_select - ]; + 'select_options' => array(), // Only used if type=select & form_callback=render_form_select + ); /** * Widget base constructor @@ -58,8 +58,8 @@ public function __construct( $id_base, $name, array $widget_options ) { */ public function form( $instance ) { - add_action( 'admin_footer', [ $this, 'enqueue_scripts' ] ); - add_action( 'customize_controls_print_footer_scripts', [ $this, 'print_customizer_scripts' ] ); + add_action( 'admin_footer', array( $this, 'enqueue_scripts' ) ); + add_action( 'customize_controls_print_footer_scripts', array( $this, 'print_customizer_scripts' ) ); ?> - get_fields( $old_instance ); - - // Force value for checkbox since they are not posted. - foreach ( $fields as $key => $field ) { - - if ( 'checkbox' === $field['type'] && ! isset( $new_instance[ $key ]['value'] ) ) { - - $new_instance[ $key ] = array( 'value' => 'no' ); - - } - - } - - // Starting at 1 since title order is 0. - $order = 1; - - foreach ( $new_instance as $key => &$instance ) { - - // Title can't be an array. - if ( 'title' === $key ) { - - $instance = call_user_func( $fields[ $key ]['sanitizer'], $instance['value'] ); - - continue; - - } - - $instance['value'] = call_user_func( $fields[ $key ]['sanitizer'], $instance['value'] ); - $instance['order'] = $order++; - - } - - return $new_instance; - - } - - /** - * Initialize fields for use on front-end of forms. - * - * @param array $instance Widget instance. - * @param array $fields (optional) Widget fields. - * @param bool $ordered (optional) Whether fields are ordered or not. - * - * @return array - */ - protected function get_fields( array $instance, array $fields = array(), $ordered = true ) { - - $order = 0; - - foreach ( $fields as $key => &$field ) { - - $common_properties = array( - 'key' => $key, - 'icon' => $key, - 'order' => ! empty( $instance[ $key ]['order'] ) ? absint( $instance[ $key ]['order'] ) : $order, - 'id' => $this->get_field_id( $key ), - 'name' => $this->get_field_name( $key ) . '[value]', - 'value' => ! empty( $instance[ $key ]['value'] ) ? $instance[ $key ]['value'] : '', - ); - - $common_properties = wp_parse_args( $common_properties, $this->field_defaults ); - $field = wp_parse_args( $field, $common_properties ); - - foreach ( array( 'escaper', 'sanitizer' ) as $key ) { - - $field[ $key ] = ! is_callable( $field[ $key ] ) ? array( $this, 'return_same_value' ) : $field[ $key ]; - - } - - $order++; - - } - - if ( $ordered ) { - - $fields = $this->order_field( $fields ); - - } - - return $fields; - - } - - /** - * Default escaper and sanitizer. - * - * @param mixed $value Value to return. - */ - public function return_same_value( $value ) { - - return $value; - - } - - /** - * Order array by field order. - * - * @param array $fields Widgets fields. - * - * @return array - */ - protected function order_field( array $fields ) { - - $this->fields = $fields; - - uksort( $fields, array( $this, 'sort_order' ) ); - - return $fields; - - } - - /** - * PHP 5.2 compatible uksort helper function. - * - * @param string $a First array key. - * @param string $b Second array key. - * - * @return int New position. - */ - private function sort_order( $a, $b ) { - - // We want title first and order of non sortable fields doesn't matter. - if ( ! $this->fields[ $a ]['sortable'] && 'title' !== $a ) { - - return 1; - - } - - return ( $this->fields[ $a ]['order'] < $this->fields[ $b ]['order'] ) ? -1 : 1; - - } - - /** - * Check if all the fields we show on the front-end are empty. - * - * @param array $fields Widget fields. - * - * @return bool - */ - protected function is_widget_empty( array $fields ) { - - foreach ( $fields as $key => $field ) { - - /** - * Filter to ignore the title when checking if a widget is empty - * - * @since NEXT - * - * @var bool - */ - $ignore_title = (bool) apply_filters( 'primer_is_widget_empty_ignore_title', false ); - - if ( 'title' === $key && $ignore_title ) { - - continue; - - } - - if ( ! empty( $field['value'] ) && $field['show_front_end'] ) { - - return false; - - } - - } - - return true; - - } - - /** - * Print current label. - * - * @param array $field Widget field. - */ - protected function print_label( array $field ) { - - printf( - ' ', - esc_attr( $field['id'] ), - esc_attr( $field['description'] ), - esc_html( $field['label'] ) - ); - - } - - /** - * Print label and wrapper - * - * @param array $field Widget field. - */ - protected function before_form_field( array $field ) { - - $classes = array( $field['type'], $field['key'] ); - - if ( ! $field['sortable'] ) { - - $classes[] = 'not-sortable'; - - } - - if ( $field['label_after'] ) { - - $classes[] = 'label-after'; - - } - - // @codingStandardsIgnoreStart - printf( - '

    ', - implode( ' ', $classes ) - ); - // @codingStandardsIgnoreEnd - - if ( ! $field['label_after'] ) { - - $this->print_label( $field ); - - } - - if ( $field['sortable'] ) { - - echo ''; - - } - - } - - /** - * Render input field for admin form. - * - * @param array $field Widget field. - */ - protected function render_form_input( array $field ) { - - $this->before_form_field( $field ); - - printf( - '', - esc_attr( $field['class'] ), - esc_attr( $field['id'] ), - esc_attr( $field['name'] ), - esc_attr( $field['type'] ), - esc_attr( $field['value'] ), - esc_attr( $field['placeholder'] ), - esc_attr( $field['atts'] ) - ); - - if ( $field['label_after'] ) { - - $this->print_label( $field ); - - } - - $this->after_form_field( $field ); - - } - - /** - * Render select field - * - * @param array $field Widget field. - */ - protected function render_form_select( array $field ) { - - $this->before_form_field( $field ); - - printf( - ''; - - if ( $field['label_after'] ) { - - $this->print_label( $field ); - - } - - $this->after_form_field( $field ); - - } - - /** - * Render textarea field for admin widget form. - * - * @param array $field Widget field. - */ - protected function render_form_textarea( array $field ) { - - $this->before_form_field( $field ); - - printf( - '', - esc_attr( $field['class'] ), - esc_attr( $field['id'] ), - esc_attr( $field['name'] ), - esc_attr( $field['placeholder'] ), - esc_textarea( $field['value'] ) - ); - - $this->after_form_field( $field ); - - } - - /** - * Close wrapper of form field. - * - * @param array $field Widget field. - */ - protected function after_form_field( array $field ) { - - if ( $field['sortable'] ) { - - echo ''; - - } - - echo '

    '; - - } - - /** - * Print beginning of front-end display. - * - * @param array $args Widget args. - * @param array $fields Widget fields. - */ - protected function before_widget( array $args, array &$fields ) { - - $title = array_shift( $fields ); - - echo $args['before_widget']; // xss ok. - - if ( ! empty( $title['value'] ) ) { - - /** - * Filter the widget title - * - * @since NEXT - * - * @var string - */ - $title = (string) apply_filters( 'widget_title', $title['value'] ); - - echo $args['before_title'] . $title . $args['after_title']; // xss ok. - - } - - } - - /** - * Print end of front-end display. - * - * @param array $args Widget args. - * @param array $fields Widget fields. - */ - protected function after_widget( array $args, array &$fields ) { - - echo $args['after_widget']; // xss ok. - - } - - /** - * Helper to output only 'checked' and not checked='checked' - * IE 9 & 10 don't support the latter. - * - * @param mixed $helper One of the values to compare. - * @param mixed $current (true) The other value to compare if not just true. - * @param bool $echo Whether to echo or just return the string. - * @return string html attribute or empty string. - */ - public function checked( $helper, $current, $echo = false ) { - - $result = (string) $helper === (string) $current ? 'checked' : ''; - - if ( $echo ) { - - echo $result; // xss ok. - - } - - return $result; - - } - - /** - * Print footer script and styles - */ - public function enqueue_scripts() {} - - /** - * Print customizer script - */ - public function print_customizer_scripts() { - - $this->enqueue_scripts(); - - } - -} diff --git a/inc/widgets/class-hero.php b/inc/widgets/class-hero.php index 3ac9f5ef..a59aa56c 100755 --- a/inc/widgets/class-hero.php +++ b/inc/widgets/class-hero.php @@ -1,11 +1,5 @@ get_fields( $instance ); - - echo '
    '; + ?> + + '; + $fields = $this->get_fields( $instance ); - echo '
    '; + echo '
    '; foreach ( $fields as $key => $field ) { @@ -72,12 +71,101 @@ public function form( $instance ) { } - echo '
    '; // End form. - echo '
    '; // End primer-widget-contact. } + /** + * Print current label. + * + * @param array $field Widget field. + */ + protected function print_label( array $field ) { + + printf( + ' ', + esc_attr( $field['id'] ), + esc_attr( $field['description'] ), + esc_html( $field['label'] ) + ); + + } + + /** + * Print label and wrapper + * + * @param array $field Widget field. + */ + protected function before_form_field( array $field ) { + + $classes = array( $field['type'], $field['key'] ); + + // @codingStandardsIgnoreStart + printf( + '

    ', + implode( ' ', $classes ) + ); + // @codingStandardsIgnoreEnd + + $this->print_label( $field ); + + } + + /** + * Render input field for admin form. + * + * @param array $field Widget field. + */ + protected function render_form_input( array $field ) { + + $this->before_form_field( $field ); + + printf( + '', + esc_attr( $field['class'] ), + esc_attr( $field['id'] ), + esc_attr( $field['name'] ), + esc_attr( $field['type'] ), + esc_attr( $field['value'] ), + esc_attr( $field['placeholder'] ), + esc_attr( $field['atts'] ) + ); + + $this->after_form_field(); + + } + + /** + * Render textarea field for admin widget form. + * + * @param array $field Widget field. + */ + protected function render_form_textarea( array $field ) { + + $this->before_form_field( $field ); + + printf( + '', + esc_attr( $field['class'] ), + esc_attr( $field['id'] ), + esc_attr( $field['name'] ), + esc_attr( $field['placeholder'] ), + esc_textarea( $field['value'] ) + ); + + $this->after_form_field(); + + } + + /** + * Close wrapper of form field. + */ + protected function after_form_field() { + + echo '

    '; + + } + /** * Front-end display. * @@ -94,7 +182,24 @@ public function widget( $args, $instance ) { } - $this->before_widget( $args, $fields ); + $title = array_shift( $fields ); + + echo $args['before_widget']; // xss ok. + + if ( ! empty( $title['value'] ) ) { + + /** + * Filter the widget title + * + * @since NEXT + * + * @var string + */ + $title = (string) apply_filters( 'widget_title', $title['value'] ); + + echo $args['before_title'] . $title . $args['after_title']; // xss ok. + + } echo '
    '; @@ -115,7 +220,7 @@ public function widget( $args, $instance ) { } /** - * Filter that let's someone change css class of the link generated by the widget. + * Filter css class of the link generated by the widget. * * @filter primer_widget_hero_link_class * @@ -125,12 +230,24 @@ public function widget( $args, $instance ) { */ $class = apply_filters( 'primer_widget_hero_link_class', array( 'button' ) ); + /** + * Filter target property of the link generated by the widget. + * + * @filter primer_widget_hero_link_class + * + * @since NEXT + * + * @var array + */ + $target = apply_filters( 'primer_widget_hero_link_target', '_self', $field ); + // @codingStandardsIgnoreStart printf( - '

    %3$s

    ', + '

    %3$s

    ', call_user_func( $fields['button_link']['escaper'], $fields['button_link']['value'] ), esc_attr( implode( ' ', $class ) ), - call_user_func( $field['escaper'], $field['value'] ) + call_user_func( $field['escaper'], $field['value'] ), + esc_attr( $target ) ); // @codingStandardsIgnoreEnd @@ -142,51 +259,84 @@ public function widget( $args, $instance ) { } - $this->after_widget( $args, $fields ); + echo $args['after_widget']; // xss ok. echo '
    '; // End div.textwidget. } + /** + * Check if all the fields we show on the front-end are empty. + * + * @param array $fields Widget fields. + * + * @return bool + */ + protected function is_widget_empty( array $fields ) { + + foreach ( $fields as $key => $field ) { + + /** + * Filter to ignore the title when checking if a widget is empty + * + * @since NEXT + * + * @var bool + */ + $ignore_title = (bool) apply_filters( 'primer_is_widget_empty_ignore_title', false ); + + if ( 'title' === $key && $ignore_title ) { + + continue; + + } + + if ( ! empty( $field['value'] ) && $field['show_front_end'] ) { + + return false; + + } + + } + + return true; + + } + /** * Initialize fields for use on front-end of forms. * * @param array $instance Widget instance. * @param array $fields Widgets fields. - * @param bool $ordered If the fields are ordered or not. * * @return array */ - protected function get_fields( array $instance, array $fields = array(), $ordered = false ) { + protected function get_fields( array $instance, array $fields = array() ) { $fields = array( - 'title' => array( - 'label' => __( 'Title:', 'primer' ), - 'description' => __( 'The title of widget. Leave empty for no title.', 'primer' ), - 'value' => ! empty( $instance['title'] ) ? $instance['title'] : '', - 'sortable' => false, + 'title' => array( + 'label' => __( 'Title:', 'primer' ), + 'description' => __( 'The title of widget. Leave empty for no title.', 'primer' ), + 'value' => ! empty( $instance['title'] ) ? $instance['title'] : '', ), - 'message' => array( + 'message' => array( 'label' => __( 'Message:', 'primer' ), 'type' => 'textarea', 'sanitizer' => array( $this, 'sanitize_message' ), 'escaper' => array( $this, 'escape_message' ), 'form_callback' => 'render_form_textarea', - 'sortable' => false, ), 'button_text' => array( 'label' => __( 'Button Text:', 'primer' ), 'type' => 'text', - 'sortable' => false, ), - 'button_link' => array( + 'button_link' => array( 'label' => __( 'Button Link URL:', 'primer' ), 'placeholder' => __( 'Paste URL or type to search', 'primer' ), 'type' => 'text', 'class' => 'widefat link', 'sanitizer' => 'esc_url_raw', 'escaper' => 'esc_url', - 'sortable' => false, 'show_front_end' => false, ), ); @@ -199,7 +349,7 @@ protected function get_fields( array $instance, array $fields = array(), $ordere * @var array */ $fields = apply_filters( 'primer_widget_hero_custom_fields', $fields, $instance ); - $fields = parent::get_fields( $instance, $fields, $ordered ); + $fields = $this->add_common_field_properties( $instance, $fields ); /** * Filter the hero widget fields @@ -212,10 +362,97 @@ protected function get_fields( array $instance, array $fields = array(), $ordere } + /** + * Takes an array of fields and add common properties to it. + * + * @param array $instance Widget instance + * @param array $fields Widget fields. + * + * @return array All the fields with comment properties. + */ + private function add_common_field_properties( array $instance, array $fields = array() ) { + + /** + * Default fields properties + * + * @var array + */ + $field_defaults = array( + 'key' => '', + 'icon' => '', + 'class' => 'widefat', + 'id' => '', + 'name' => '', + 'label' => '', + 'description' => '', + 'type' => 'text', + 'sanitizer' => 'sanitize_text_field', + 'escaper' => 'esc_html', + 'form_callback' => 'render_form_input', + 'default' => '', // If you need a default value. + 'value' => '', + 'placeholder' => '', + 'atts' => '', // Input attributes. + 'show_front_end' => true, // Are we showing this field on the front end? + 'show_empty' => false, // Show the field even if the value is empty. + ); + + foreach ( $fields as $key => &$field ) { + + $common_properties = array( + 'key' => $key, + 'icon' => $key, + 'id' => $this->get_field_id( $key ), + 'name' => $this->get_field_name( $key ) . '[value]', + 'value' => ! empty( $instance[ $key ]['value'] ) ? $instance[ $key ]['value'] : '', + ); + + $common_properties = wp_parse_args( $common_properties, $field_defaults ); + $field = wp_parse_args( $field, $common_properties ); + + } + + return $fields; + + } + + /** + * Sanitize widget form values as they are saved. + * + * @param array $new_instance Values just sent to be saved. + * @param array $old_instance Previously saved values from database. + * + * @return array Updated safe values to be saved. + */ + public function update( $new_instance, $old_instance ) { + + $fields = $this->get_fields( $old_instance ); + + foreach ( $new_instance as $key => &$instance ) { + + // Title can't be an array. + if ( 'title' === $key ) { + + $instance = call_user_func( $fields[ $key ]['sanitizer'], $instance['value'] ); + + continue; + + } + + $instance['value'] = call_user_func( $fields[ $key ]['sanitizer'], $instance['value'] ); + + } + + return $new_instance; + + } + /** * Sanitize field message. * * @param string $value Message value. + * + * @return string */ public function sanitize_message( $value ) { @@ -227,6 +464,8 @@ public function sanitize_message( $value ) { * Escape field message. * * @param string $value Message value. + * + * @return string */ public function escape_message( $value ) { @@ -243,7 +482,13 @@ public function enqueue_scripts() { wp_enqueue_script( 'jquery-ui-autocomplete' ); - wp_enqueue_script( 'primer-widgets-hero-admin', get_template_directory_uri() . "/assets/js/widgets/hero-admin{$suffix}.js", array( 'jquery', 'jquery-ui-autocomplete' ), PRIMER_VERSION, true ); + wp_enqueue_script( + 'primer-widgets-hero-admin', + get_template_directory_uri() . "/assets/js/widgets/hero-admin{$suffix}.js", + array( 'jquery', 'jquery-ui-autocomplete' ), + PRIMER_VERSION, + true + ); // We need the internal linking token. wp_localize_script( From 3cf1b8746f9fb47e618deaf8090e53f2950a35ad Mon Sep 17 00:00:00 2001 From: Jonathan Bardo Date: Sun, 26 Feb 2017 17:47:22 -0500 Subject: [PATCH 12/19] Remove uneeded common properties --- inc/widgets/class-hero.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/inc/widgets/class-hero.php b/inc/widgets/class-hero.php index a59aa56c..faf0f869 100755 --- a/inc/widgets/class-hero.php +++ b/inc/widgets/class-hero.php @@ -37,7 +37,7 @@ public function __construct() { * * @param array $instance The widget instance values. * - * @return string|void + * @return string */ public function form( $instance ) { @@ -121,14 +121,13 @@ protected function render_form_input( array $field ) { $this->before_form_field( $field ); printf( - '', + '', esc_attr( $field['class'] ), esc_attr( $field['id'] ), esc_attr( $field['name'] ), esc_attr( $field['type'] ), esc_attr( $field['value'] ), - esc_attr( $field['placeholder'] ), - esc_attr( $field['atts'] ) + esc_attr( $field['placeholder'] ) ); $this->after_form_field(); @@ -373,7 +372,7 @@ protected function get_fields( array $instance, array $fields = array() ) { private function add_common_field_properties( array $instance, array $fields = array() ) { /** - * Default fields properties + * Default fields properties. * * @var array */ @@ -389,12 +388,9 @@ private function add_common_field_properties( array $instance, array $fields = a 'sanitizer' => 'sanitize_text_field', 'escaper' => 'esc_html', 'form_callback' => 'render_form_input', - 'default' => '', // If you need a default value. 'value' => '', 'placeholder' => '', - 'atts' => '', // Input attributes. 'show_front_end' => true, // Are we showing this field on the front end? - 'show_empty' => false, // Show the field even if the value is empty. ); foreach ( $fields as $key => &$field ) { From 37714ec4b1fef9387a8cfa01104fb737c6c6f881 Mon Sep 17 00:00:00 2001 From: Jonathan Bardo Date: Mon, 27 Feb 2017 08:56:59 -0500 Subject: [PATCH 13/19] Add return statement --- inc/widgets/class-hero.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/widgets/class-hero.php b/inc/widgets/class-hero.php index faf0f869..6a52d585 100755 --- a/inc/widgets/class-hero.php +++ b/inc/widgets/class-hero.php @@ -37,7 +37,7 @@ public function __construct() { * * @param array $instance The widget instance values. * - * @return string + * @return void */ public function form( $instance ) { @@ -364,7 +364,7 @@ protected function get_fields( array $instance, array $fields = array() ) { /** * Takes an array of fields and add common properties to it. * - * @param array $instance Widget instance + * @param array $instance Widget instance. * @param array $fields Widget fields. * * @return array All the fields with comment properties. From 7d60f59b5bfdc9e56bd4e3c2f05c7068859fd9a1 Mon Sep 17 00:00:00 2001 From: Frankie Jarrett Date: Mon, 27 Feb 2017 21:21:37 -0600 Subject: [PATCH 14/19] Refactor by Frankie --- .dev/sass/layouts/_hero.scss | 4 + .../hero-admin.js => admin/hero-widget.js} | 18 +- assets/js/admin/hero-widget.min.js | 1 + assets/js/widgets/hero-admin.min.js | 1 - functions.php | 6 +- inc/hero-widget.php | 246 +++++++++ inc/widgets/class-hero.php | 511 ------------------ phpcs.ruleset.xml | 11 +- style-rtl.css | 2 + style.css | 2 + 10 files changed, 274 insertions(+), 528 deletions(-) rename assets/js/{widgets/hero-admin.js => admin/hero-widget.js} (91%) create mode 100644 assets/js/admin/hero-widget.min.js delete mode 100644 assets/js/widgets/hero-admin.min.js create mode 100755 inc/hero-widget.php delete mode 100755 inc/widgets/class-hero.php diff --git a/.dev/sass/layouts/_hero.scss b/.dev/sass/layouts/_hero.scss index c27244bc..ec0444f4 100644 --- a/.dev/sass/layouts/_hero.scss +++ b/.dev/sass/layouts/_hero.scss @@ -36,6 +36,10 @@ list-style: none; } } + + b, strong { + font-weight: 600; + } } label, input, select, textarea { diff --git a/assets/js/widgets/hero-admin.js b/assets/js/admin/hero-widget.js similarity index 91% rename from assets/js/widgets/hero-admin.js rename to assets/js/admin/hero-widget.js index d19bc5f3..10ae2350 100755 --- a/assets/js/widgets/hero-admin.js +++ b/assets/js/admin/hero-widget.js @@ -1,6 +1,6 @@ -/* global jQuery, primer_widgets_hero_admin */ +/* global jQuery, primer_admin_hero_widget */ -(function( $ ) { +( function( $ ) { var link = { @@ -44,7 +44,7 @@ action: 'wp-link-ajax', page: 1, search: request.term, - _ajax_linking_nonce: primer_widgets_hero_admin._ajax_linking_nonce + _ajax_linking_nonce: primer_admin_hero_widget._ajax_linking_nonce }, function( data ) { @@ -73,7 +73,7 @@ $input.val( ui.item.permalink ); - // This is for the customizer + // This is for the customizer. $input.trigger( 'change' ); return false; @@ -143,7 +143,7 @@ ui.item.attr( 'aria-selected', 'true' ); - }) + } ) .on( 'menublur', function() { /* @@ -152,15 +152,15 @@ */ $( this ).find( '[aria-selected="true"]' ).removeAttr( 'aria-selected' ); - }); + } ); - } // end init + } // end init. }; function addAutocomplete() { - $( '.primer-widget-hero input.link' ).each( function() { + $( '.primer-hero-widget input.link-autocomplete' ).each( function() { link.init( this ); @@ -171,4 +171,4 @@ $( document ).ready( addAutocomplete ); $( document ).on( 'primer.widgets.change', addAutocomplete ); -})( jQuery ); +} )( jQuery ); diff --git a/assets/js/admin/hero-widget.min.js b/assets/js/admin/hero-widget.min.js new file mode 100644 index 00000000..b6be713a --- /dev/null +++ b/assets/js/admin/hero-widget.min.js @@ -0,0 +1 @@ +!function(a){function b(){a(".primer-hero-widget input.link-autocomplete").each(function(){c.init(this)})}var c={init:function(b){if(a&&a.ui&&a.ui.autocomplete){var c,d,e=a(b);e.on("keydown",function(){e.removeAttr("aria-activedescendant")}).autocomplete({source:function(b,e){return d===b.term?void e(c):/^https?:/.test(b.term)||b.term.indexOf(".")!==-1?e():(a.post(window.ajaxurl,{action:"wp-link-ajax",page:1,search:b.term,_ajax_linking_nonce:primer_admin_hero_widget._ajax_linking_nonce},function(a){c=a,e(a)},"json"),void(d=b.term))},focus:function(a,b){e.attr("aria-activedescendant","mce-wp-autocomplete-"+b.item.ID),a.preventDefault()},select:function(a,b){return e.val(b.item.permalink),e.trigger("change"),!1},open:function(){e.attr("aria-expanded","true")},close:function(){e.attr("aria-expanded","false")},minLength:2,position:{my:"left top+2"}}).autocomplete("instance")._renderItem=function(b,c){return a('
  • ').append(""+c.title+' '+c.info+"").appendTo(b)},e.attr({role:"combobox","aria-autocomplete":"list","aria-expanded":"false","aria-owns":e.autocomplete("widget").attr("id")}).on("focus",function(){var a=e.val();a&&!/^https?:/.test(a)&&e.autocomplete("search")}).autocomplete("widget").css({"z-index":9999999}).attr("role","listbox").removeAttr("tabindex").on("menufocus",function(a,b){b.item.attr("aria-selected","true")}).on("menublur",function(){a(this).find('[aria-selected="true"]').removeAttr("aria-selected")})}}};a(document).ready(b),a(document).on("primer.widgets.change",b)}(jQuery); \ No newline at end of file diff --git a/assets/js/widgets/hero-admin.min.js b/assets/js/widgets/hero-admin.min.js deleted file mode 100644 index f0ba7f8f..00000000 --- a/assets/js/widgets/hero-admin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(a){function b(){a(".primer-widget-hero input.link").each(function(){c.init(this)})}var c={init:function(b){if(a&&a.ui&&a.ui.autocomplete){var c,d,e=a(b);e.on("keydown",function(){e.removeAttr("aria-activedescendant")}).autocomplete({source:function(b,e){return d===b.term?void e(c):/^https?:/.test(b.term)||b.term.indexOf(".")!==-1?e():(a.post(window.ajaxurl,{action:"wp-link-ajax",page:1,search:b.term,_ajax_linking_nonce:primer_widgets_hero_admin._ajax_linking_nonce},function(a){c=a,e(a)},"json"),void(d=b.term))},focus:function(a,b){e.attr("aria-activedescendant","mce-wp-autocomplete-"+b.item.ID),a.preventDefault()},select:function(a,b){return e.val(b.item.permalink),e.trigger("change"),!1},open:function(){e.attr("aria-expanded","true")},close:function(){e.attr("aria-expanded","false")},minLength:2,position:{my:"left top+2"}}).autocomplete("instance")._renderItem=function(b,c){return a('
  • ').append(""+c.title+' '+c.info+"").appendTo(b)},e.attr({role:"combobox","aria-autocomplete":"list","aria-expanded":"false","aria-owns":e.autocomplete("widget").attr("id")}).on("focus",function(){var a=e.val();a&&!/^https?:/.test(a)&&e.autocomplete("search")}).autocomplete("widget").css({"z-index":9999999}).attr("role","listbox").removeAttr("tabindex").on("menufocus",function(a,b){b.item.attr("aria-selected","true")}).on("menublur",function(){a(this).find('[aria-selected="true"]').removeAttr("aria-selected")})}}};a(document).ready(b),a(document).on("primer.widgets.change",b)}(jQuery); \ No newline at end of file diff --git a/functions.php b/functions.php index 89cbd0b2..9683ffde 100755 --- a/functions.php +++ b/functions.php @@ -437,16 +437,16 @@ function primer_register_sidebars() { add_action( 'widgets_init', 'primer_register_sidebars' ); /** - * Register Primer hero widget. + * Register Primer widgets. * * @link http://codex.wordpress.org/Function_Reference/register_widget * @since NEXT */ function primer_register_widgets() { - require_once get_template_directory() . '/inc/widgets/class-hero.php'; + require_once get_template_directory() . '/inc/hero-widget.php'; - register_widget( 'Primer_Hero' ); + register_widget( 'Primer_Hero_Widget' ); } add_action( 'widgets_init', 'primer_register_widgets' ); diff --git a/inc/hero-widget.php b/inc/hero-widget.php new file mode 100755 index 00000000..c7a4d332 --- /dev/null +++ b/inc/hero-widget.php @@ -0,0 +1,246 @@ + true, + 'classname' => 'widget_text primer-widgets primer-hero-widget', + 'description' => sprintf( + esc_html_x( "A %s theme widget designed for the Hero area on your site's front page.", 'theme name', 'primer' ), + esc_html( $this->get_current_theme_name() ) + ), + ); + + parent::__construct( 'primer-hero-text', esc_html__( 'Hero Text', 'primer' ), $widget_options ); + + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); + add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); + + } + + /** + * Display the widget on the front-end. + * + * @since NEXT + * + * @param array $args Display arguments including `before_title`, `after_title`, `before_widget`, and `after_widget`. + * @param array $instance The settings for the particular instance of the widget. + */ + public function widget( $args, $instance ) { + + /** + * Filter the widget title. + * + * @link [widget_title](https://codex.wordpress.org/Plugin_API/Filter_Reference/widget_title) + * @since NEXT + * + * @var string + */ + $title = ! empty( $instance['title'] ) ? (string) apply_filters( 'widget_title', $instance['title'], $instance, 'primer-hero' ) : null; + + /** + * Filter the widget text. + * + * @since NEXT + * + * @var string + */ + $text = ! empty( $instance['text'] ) ? (string) apply_filters( 'widget_text', $instance['text'] ) : null; + + $button_text = ! empty( $instance['button_text'] ) ? $instance['button_text'] : null; + $button_link = ! empty( $instance['button_link'] ) ? $instance['button_link'] : null; + + // The `button_link` can be empty. + if ( ! $title && ! $text && ! $button_text ) { + + return; + + } + + echo $args['before_widget']; // xss ok. + + ?> +
    + + + + + + + + + + + + + + + +

    + + + +
    + + + +
    + +

    + + +

    + +

    + + +

    + +

    + + +

    + +

    + + +

    + +
    + wp_create_nonce( 'internal-linking' ), + ) + ); + + } + + /** + * Return the current theme name. + * + * Looks for the `current_theme` option first, and if not + * present will fetch it using `wp_get_theme()`. + * + * @since NEXT + * + * @return string + */ + protected function get_current_theme_name() { + + if ( $current_theme = get_option( 'current_theme' ) ) { + + return $current_theme; + + } + + $theme = wp_get_theme(); + + return $theme->get( 'Name' ); + + } + +} diff --git a/inc/widgets/class-hero.php b/inc/widgets/class-hero.php deleted file mode 100755 index 6a52d585..00000000 --- a/inc/widgets/class-hero.php +++ /dev/null @@ -1,511 +0,0 @@ - 'primer-widgets primer-widget-hero widget_text', - 'description' => __( 'A specialy crafted widget to be used in the hero section of Primer related themes.', 'primer' ), - 'customize_selective_refresh' => true, - ); - - parent::__construct( - 'primer_hero', - __( 'Homepage Hero Widget', 'primer' ), - $widget_options - ); - - } - - /** - * Widget form fields. - * - * @param array $instance The widget instance values. - * - * @return void - */ - public function form( $instance ) { - - add_action( 'admin_footer', array( $this, 'enqueue_scripts' ) ); - add_action( 'customize_controls_print_footer_scripts', array( $this, 'print_customizer_scripts' ) ); - - ?> - - get_fields( $instance ); - - echo '
    '; - - foreach ( $fields as $key => $field ) { - - $method = $field['form_callback']; - - if ( is_callable( array( $this, $method ) ) ) { - - $this->$method( $field ); - - } - - } - - echo '
    '; // End primer-widget-contact. - - } - - /** - * Print current label. - * - * @param array $field Widget field. - */ - protected function print_label( array $field ) { - - printf( - ' ', - esc_attr( $field['id'] ), - esc_attr( $field['description'] ), - esc_html( $field['label'] ) - ); - - } - - /** - * Print label and wrapper - * - * @param array $field Widget field. - */ - protected function before_form_field( array $field ) { - - $classes = array( $field['type'], $field['key'] ); - - // @codingStandardsIgnoreStart - printf( - '

    ', - implode( ' ', $classes ) - ); - // @codingStandardsIgnoreEnd - - $this->print_label( $field ); - - } - - /** - * Render input field for admin form. - * - * @param array $field Widget field. - */ - protected function render_form_input( array $field ) { - - $this->before_form_field( $field ); - - printf( - '', - esc_attr( $field['class'] ), - esc_attr( $field['id'] ), - esc_attr( $field['name'] ), - esc_attr( $field['type'] ), - esc_attr( $field['value'] ), - esc_attr( $field['placeholder'] ) - ); - - $this->after_form_field(); - - } - - /** - * Render textarea field for admin widget form. - * - * @param array $field Widget field. - */ - protected function render_form_textarea( array $field ) { - - $this->before_form_field( $field ); - - printf( - '', - esc_attr( $field['class'] ), - esc_attr( $field['id'] ), - esc_attr( $field['name'] ), - esc_attr( $field['placeholder'] ), - esc_textarea( $field['value'] ) - ); - - $this->after_form_field(); - - } - - /** - * Close wrapper of form field. - */ - protected function after_form_field() { - - echo '

    '; - - } - - /** - * Front-end display. - * - * @param array $args Widget arguements. - * @param array $instance Widget instance arguements. - */ - public function widget( $args, $instance ) { - - $fields = $this->get_fields( $instance ); - - if ( $this->is_widget_empty( $fields ) ) { - - return; - - } - - $title = array_shift( $fields ); - - echo $args['before_widget']; // xss ok. - - if ( ! empty( $title['value'] ) ) { - - /** - * Filter the widget title - * - * @since NEXT - * - * @var string - */ - $title = (string) apply_filters( 'widget_title', $title['value'] ); - - echo $args['before_title'] . $title . $args['after_title']; // xss ok. - - } - - echo '
    '; - - foreach ( $fields as $key => $field ) { - - if ( empty( $field['value'] ) || ! $field['show_front_end'] ) { - - continue; - - } - - if ( 'button_text' === $key ) { - - if ( ! isset( $fields['button_link'] ) || empty( $fields['button_link']['value'] ) ) { - - continue; - - } - - /** - * Filter css class of the link generated by the widget. - * - * @filter primer_widget_hero_link_class - * - * @since NEXT - * - * @var array - */ - $class = apply_filters( 'primer_widget_hero_link_class', array( 'button' ) ); - - /** - * Filter target property of the link generated by the widget. - * - * @filter primer_widget_hero_link_class - * - * @since NEXT - * - * @var array - */ - $target = apply_filters( 'primer_widget_hero_link_target', '_self', $field ); - - // @codingStandardsIgnoreStart - printf( - '

    %3$s

    ', - call_user_func( $fields['button_link']['escaper'], $fields['button_link']['value'] ), - esc_attr( implode( ' ', $class ) ), - call_user_func( $field['escaper'], $field['value'] ), - esc_attr( $target ) - ); - // @codingStandardsIgnoreEnd - - continue; - - } - - echo call_user_func( $field['escaper'], $field['value'] ); // xss ok. - - } - - echo $args['after_widget']; // xss ok. - - echo '
    '; // End div.textwidget. - - } - - /** - * Check if all the fields we show on the front-end are empty. - * - * @param array $fields Widget fields. - * - * @return bool - */ - protected function is_widget_empty( array $fields ) { - - foreach ( $fields as $key => $field ) { - - /** - * Filter to ignore the title when checking if a widget is empty - * - * @since NEXT - * - * @var bool - */ - $ignore_title = (bool) apply_filters( 'primer_is_widget_empty_ignore_title', false ); - - if ( 'title' === $key && $ignore_title ) { - - continue; - - } - - if ( ! empty( $field['value'] ) && $field['show_front_end'] ) { - - return false; - - } - - } - - return true; - - } - - /** - * Initialize fields for use on front-end of forms. - * - * @param array $instance Widget instance. - * @param array $fields Widgets fields. - * - * @return array - */ - protected function get_fields( array $instance, array $fields = array() ) { - - $fields = array( - 'title' => array( - 'label' => __( 'Title:', 'primer' ), - 'description' => __( 'The title of widget. Leave empty for no title.', 'primer' ), - 'value' => ! empty( $instance['title'] ) ? $instance['title'] : '', - ), - 'message' => array( - 'label' => __( 'Message:', 'primer' ), - 'type' => 'textarea', - 'sanitizer' => array( $this, 'sanitize_message' ), - 'escaper' => array( $this, 'escape_message' ), - 'form_callback' => 'render_form_textarea', - ), - 'button_text' => array( - 'label' => __( 'Button Text:', 'primer' ), - 'type' => 'text', - ), - 'button_link' => array( - 'label' => __( 'Button Link URL:', 'primer' ), - 'placeholder' => __( 'Paste URL or type to search', 'primer' ), - 'type' => 'text', - 'class' => 'widefat link', - 'sanitizer' => 'esc_url_raw', - 'escaper' => 'esc_url', - 'show_front_end' => false, - ), - ); - - /** - * Register custom fields for the hero widgets. - * - * @since NEXT - * - * @var array - */ - $fields = apply_filters( 'primer_widget_hero_custom_fields', $fields, $instance ); - $fields = $this->add_common_field_properties( $instance, $fields ); - - /** - * Filter the hero widget fields - * - * @since NEXT - * - * @var array - */ - return (array) apply_filters( 'primer_widget_hero_fields', $fields, $instance ); - - } - - /** - * Takes an array of fields and add common properties to it. - * - * @param array $instance Widget instance. - * @param array $fields Widget fields. - * - * @return array All the fields with comment properties. - */ - private function add_common_field_properties( array $instance, array $fields = array() ) { - - /** - * Default fields properties. - * - * @var array - */ - $field_defaults = array( - 'key' => '', - 'icon' => '', - 'class' => 'widefat', - 'id' => '', - 'name' => '', - 'label' => '', - 'description' => '', - 'type' => 'text', - 'sanitizer' => 'sanitize_text_field', - 'escaper' => 'esc_html', - 'form_callback' => 'render_form_input', - 'value' => '', - 'placeholder' => '', - 'show_front_end' => true, // Are we showing this field on the front end? - ); - - foreach ( $fields as $key => &$field ) { - - $common_properties = array( - 'key' => $key, - 'icon' => $key, - 'id' => $this->get_field_id( $key ), - 'name' => $this->get_field_name( $key ) . '[value]', - 'value' => ! empty( $instance[ $key ]['value'] ) ? $instance[ $key ]['value'] : '', - ); - - $common_properties = wp_parse_args( $common_properties, $field_defaults ); - $field = wp_parse_args( $field, $common_properties ); - - } - - return $fields; - - } - - /** - * Sanitize widget form values as they are saved. - * - * @param array $new_instance Values just sent to be saved. - * @param array $old_instance Previously saved values from database. - * - * @return array Updated safe values to be saved. - */ - public function update( $new_instance, $old_instance ) { - - $fields = $this->get_fields( $old_instance ); - - foreach ( $new_instance as $key => &$instance ) { - - // Title can't be an array. - if ( 'title' === $key ) { - - $instance = call_user_func( $fields[ $key ]['sanitizer'], $instance['value'] ); - - continue; - - } - - $instance['value'] = call_user_func( $fields[ $key ]['sanitizer'], $instance['value'] ); - - } - - return $new_instance; - - } - - /** - * Sanitize field message. - * - * @param string $value Message value. - * - * @return string - */ - public function sanitize_message( $value ) { - - return current_user_can( 'unfiltered_html' ) ? $value : wp_kses_post( stripslashes( $value ) ); - - } - - /** - * Escape field message. - * - * @param string $value Message value. - * - * @return string - */ - public function escape_message( $value ) { - - return wpautop( apply_filters( 'widget_text', $value ) ); - - } - - /** - * Print footer script and styles. - */ - public function enqueue_scripts() { - - $suffix = SCRIPT_DEBUG ? '' : '.min'; - - wp_enqueue_script( 'jquery-ui-autocomplete' ); - - wp_enqueue_script( - 'primer-widgets-hero-admin', - get_template_directory_uri() . "/assets/js/widgets/hero-admin{$suffix}.js", - array( 'jquery', 'jquery-ui-autocomplete' ), - PRIMER_VERSION, - true - ); - - // We need the internal linking token. - wp_localize_script( - 'primer-widgets-hero-admin', - 'primer_widgets_hero_admin', - array( - '_ajax_linking_nonce' => wp_create_nonce( 'internal-linking' ), - ) - ); - - } - - /** - * Print customizer script - */ - public function print_customizer_scripts() { - - $this->enqueue_scripts(); - - wp_print_scripts( 'primer-widgets-hero-admin' ); - - } - -} diff --git a/phpcs.ruleset.xml b/phpcs.ruleset.xml index 1b9297a1..9889eabe 100644 --- a/phpcs.ruleset.xml +++ b/phpcs.ruleset.xml @@ -1,13 +1,16 @@ - - Generally-applicable sniffs for WordPress plugins + + Generally-applicable sniffs for WordPress themes - + - */dev/* + */.dev/* + */.git/* + */build/* */node_modules/* + */tests/* */vendor/* diff --git a/style-rtl.css b/style-rtl.css index d9047b9a..ed4d8aa6 100644 --- a/style-rtl.css +++ b/style-rtl.css @@ -1681,6 +1681,8 @@ body.no-max-width .page-title-container .page-header { padding-right: 0; } .hero .widget ul li, .hero .widget ol li { list-style: none; } + .hero .widget b, .hero .widget strong { + font-weight: 600; } .hero label, .hero input, .hero select, .hero textarea { display: inline; width: auto; } diff --git a/style.css b/style.css index 63e363aa..8989bd0c 100644 --- a/style.css +++ b/style.css @@ -1681,6 +1681,8 @@ body.no-max-width .page-title-container .page-header { padding-left: 0; } .hero .widget ul li, .hero .widget ol li { list-style: none; } + .hero .widget b, .hero .widget strong { + font-weight: 600; } .hero label, .hero input, .hero select, .hero textarea { display: inline; width: auto; } From 7949c7a80ac5231c0339c659c65a2421befb57ae Mon Sep 17 00:00:00 2001 From: Frankie Jarrett Date: Mon, 27 Feb 2017 21:40:32 -0600 Subject: [PATCH 15/19] Rename everything to "hero-text" --- .../{hero-widget.js => hero-text-widget.js} | 6 ++-- assets/js/admin/hero-text-widget.min.js | 1 + assets/js/admin/hero-widget.min.js | 1 - functions.php | 4 +-- inc/{hero-widget.php => hero-text-widget.php} | 33 +++++++++++-------- 5 files changed, 26 insertions(+), 19 deletions(-) rename assets/js/admin/{hero-widget.js => hero-text-widget.js} (94%) create mode 100644 assets/js/admin/hero-text-widget.min.js delete mode 100644 assets/js/admin/hero-widget.min.js rename inc/{hero-widget.php => hero-text-widget.php} (87%) diff --git a/assets/js/admin/hero-widget.js b/assets/js/admin/hero-text-widget.js similarity index 94% rename from assets/js/admin/hero-widget.js rename to assets/js/admin/hero-text-widget.js index 10ae2350..31991d30 100755 --- a/assets/js/admin/hero-widget.js +++ b/assets/js/admin/hero-text-widget.js @@ -1,4 +1,4 @@ -/* global jQuery, primer_admin_hero_widget */ +/* global jQuery, primer_hero_text_widget */ ( function( $ ) { @@ -44,7 +44,7 @@ action: 'wp-link-ajax', page: 1, search: request.term, - _ajax_linking_nonce: primer_admin_hero_widget._ajax_linking_nonce + _ajax_linking_nonce: primer_hero_text_widget._ajax_linking_nonce }, function( data ) { @@ -160,7 +160,7 @@ function addAutocomplete() { - $( '.primer-hero-widget input.link-autocomplete' ).each( function() { + $( '.primer-hero-text-widget input.link-autocomplete' ).each( function() { link.init( this ); diff --git a/assets/js/admin/hero-text-widget.min.js b/assets/js/admin/hero-text-widget.min.js new file mode 100644 index 00000000..592cd1b8 --- /dev/null +++ b/assets/js/admin/hero-text-widget.min.js @@ -0,0 +1 @@ +!function(a){function b(){a(".primer-hero-text-widget input.link-autocomplete").each(function(){c.init(this)})}var c={init:function(b){if(a&&a.ui&&a.ui.autocomplete){var c,d,e=a(b);e.on("keydown",function(){e.removeAttr("aria-activedescendant")}).autocomplete({source:function(b,e){return d===b.term?void e(c):/^https?:/.test(b.term)||b.term.indexOf(".")!==-1?e():(a.post(window.ajaxurl,{action:"wp-link-ajax",page:1,search:b.term,_ajax_linking_nonce:primer_hero_text_widget._ajax_linking_nonce},function(a){c=a,e(a)},"json"),void(d=b.term))},focus:function(a,b){e.attr("aria-activedescendant","mce-wp-autocomplete-"+b.item.ID),a.preventDefault()},select:function(a,b){return e.val(b.item.permalink),e.trigger("change"),!1},open:function(){e.attr("aria-expanded","true")},close:function(){e.attr("aria-expanded","false")},minLength:2,position:{my:"left top+2"}}).autocomplete("instance")._renderItem=function(b,c){return a('
  • ').append(""+c.title+' '+c.info+"").appendTo(b)},e.attr({role:"combobox","aria-autocomplete":"list","aria-expanded":"false","aria-owns":e.autocomplete("widget").attr("id")}).on("focus",function(){var a=e.val();a&&!/^https?:/.test(a)&&e.autocomplete("search")}).autocomplete("widget").css({"z-index":9999999}).attr("role","listbox").removeAttr("tabindex").on("menufocus",function(a,b){b.item.attr("aria-selected","true")}).on("menublur",function(){a(this).find('[aria-selected="true"]').removeAttr("aria-selected")})}}};a(document).ready(b),a(document).on("primer.widgets.change",b)}(jQuery); \ No newline at end of file diff --git a/assets/js/admin/hero-widget.min.js b/assets/js/admin/hero-widget.min.js deleted file mode 100644 index b6be713a..00000000 --- a/assets/js/admin/hero-widget.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(a){function b(){a(".primer-hero-widget input.link-autocomplete").each(function(){c.init(this)})}var c={init:function(b){if(a&&a.ui&&a.ui.autocomplete){var c,d,e=a(b);e.on("keydown",function(){e.removeAttr("aria-activedescendant")}).autocomplete({source:function(b,e){return d===b.term?void e(c):/^https?:/.test(b.term)||b.term.indexOf(".")!==-1?e():(a.post(window.ajaxurl,{action:"wp-link-ajax",page:1,search:b.term,_ajax_linking_nonce:primer_admin_hero_widget._ajax_linking_nonce},function(a){c=a,e(a)},"json"),void(d=b.term))},focus:function(a,b){e.attr("aria-activedescendant","mce-wp-autocomplete-"+b.item.ID),a.preventDefault()},select:function(a,b){return e.val(b.item.permalink),e.trigger("change"),!1},open:function(){e.attr("aria-expanded","true")},close:function(){e.attr("aria-expanded","false")},minLength:2,position:{my:"left top+2"}}).autocomplete("instance")._renderItem=function(b,c){return a('
  • ').append(""+c.title+' '+c.info+"").appendTo(b)},e.attr({role:"combobox","aria-autocomplete":"list","aria-expanded":"false","aria-owns":e.autocomplete("widget").attr("id")}).on("focus",function(){var a=e.val();a&&!/^https?:/.test(a)&&e.autocomplete("search")}).autocomplete("widget").css({"z-index":9999999}).attr("role","listbox").removeAttr("tabindex").on("menufocus",function(a,b){b.item.attr("aria-selected","true")}).on("menublur",function(){a(this).find('[aria-selected="true"]').removeAttr("aria-selected")})}}};a(document).ready(b),a(document).on("primer.widgets.change",b)}(jQuery); \ No newline at end of file diff --git a/functions.php b/functions.php index 9683ffde..e4131a16 100755 --- a/functions.php +++ b/functions.php @@ -444,9 +444,9 @@ function primer_register_sidebars() { */ function primer_register_widgets() { - require_once get_template_directory() . '/inc/hero-widget.php'; + require_once get_template_directory() . '/inc/hero-text-widget.php'; - register_widget( 'Primer_Hero_Widget' ); + register_widget( 'Primer_Hero_Text_Widget' ); } add_action( 'widgets_init', 'primer_register_widgets' ); diff --git a/inc/hero-widget.php b/inc/hero-text-widget.php similarity index 87% rename from inc/hero-widget.php rename to inc/hero-text-widget.php index c7a4d332..bfa7197b 100755 --- a/inc/hero-widget.php +++ b/inc/hero-text-widget.php @@ -1,8 +1,8 @@ true, - 'classname' => 'widget_text primer-widgets primer-hero-widget', + 'classname' => 'widget_text primer-widgets primer-hero-text-widget', 'description' => sprintf( esc_html_x( "A %s theme widget designed for the Hero area on your site's front page.", 'theme name', 'primer' ), esc_html( $this->get_current_theme_name() ) @@ -46,21 +46,28 @@ public function widget( $args, $instance ) { /** * Filter the widget title. * - * @link [widget_title](https://codex.wordpress.org/Plugin_API/Filter_Reference/widget_title) + * @link https://developer.wordpress.org/reference/hooks/widget_title/ * @since NEXT * + * @param array $instance An array of the widget's settings. + * @param string $id_base The widget ID. + * * @var string */ - $title = ! empty( $instance['title'] ) ? (string) apply_filters( 'widget_title', $instance['title'], $instance, 'primer-hero' ) : null; + $title = ! empty( $instance['title'] ) ? (string) apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) : null; /** * Filter the widget text. * + * @link https://developer.wordpress.org/reference/hooks/widget_text/ * @since NEXT * + * @param array $instance Array of settings for the current widget. + * @param Primer_Hero_Text_Widget $this Current Hero Text widget instance. + * * @var string */ - $text = ! empty( $instance['text'] ) ? (string) apply_filters( 'widget_text', $instance['text'] ) : null; + $text = ! empty( $instance['text'] ) ? (string) apply_filters( 'widget_text', $instance['text'], $instance, $this ) : null; $button_text = ! empty( $instance['button_text'] ) ? $instance['button_text'] : null; $button_link = ! empty( $instance['button_link'] ) ? $instance['button_link'] : null; @@ -75,7 +82,7 @@ public function widget( $args, $instance ) { echo $args['before_widget']; // xss ok. ?> -
    +
    @@ -126,7 +133,7 @@ public function form( $instance ) { } )( jQuery ); -
    +

    @@ -201,8 +208,8 @@ public function enqueue_scripts( $hook_suffix ) { wp_enqueue_script( 'jquery-ui-autocomplete' ); wp_enqueue_script( - 'primer-admin-hero-widget', - get_template_directory_uri() . "/assets/js/admin/hero-widget{$suffix}.js", + 'primer-admin-hero-text-widget', + get_template_directory_uri() . "/assets/js/admin/hero-text-widget{$suffix}.js", array( 'jquery', 'jquery-ui-autocomplete' ), PRIMER_VERSION, true @@ -210,8 +217,8 @@ public function enqueue_scripts( $hook_suffix ) { // We need the internal linking token. wp_localize_script( - 'primer-admin-hero-widget', - 'primer_admin_hero_widget', + 'primer-admin-hero-text-widget', + 'primer_hero_text_widget', array( '_ajax_linking_nonce' => wp_create_nonce( 'internal-linking' ), ) From ee34ece73addf332710018dfe4e0e949d110b2b8 Mon Sep 17 00:00:00 2001 From: Frankie Jarrett Date: Tue, 28 Feb 2017 12:31:37 -0600 Subject: [PATCH 16/19] Update comment for why inline script exists --- inc/hero-text-widget.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/hero-text-widget.php b/inc/hero-text-widget.php index bfa7197b..d1607db6 100755 --- a/inc/hero-text-widget.php +++ b/inc/hero-text-widget.php @@ -127,7 +127,7 @@ public function form( $instance ) { + +

    @@ -154,7 +160,7 @@ public function form( $instance ) {

    - +