├── assets ├── img │ ├── devman.png │ ├── heart.png │ ├── stripes.png │ ├── hand-with-heart.png │ └── metabox │ │ ├── blogpage-info.png │ │ ├── wooshop-info.png │ │ └── frontpage-info.png ├── sass │ ├── _mixins.scss │ ├── cs-scan.scss │ ├── cs-cloning.scss │ ├── _custom-sidebars-checkup.scss │ └── cs-visibility.scss ├── js │ ├── src │ │ ├── metabox-allow-entry-author.js │ │ ├── metabox-roles.js │ │ ├── metabox-custom-taxonomies.js │ │ ├── cs-visibility.js │ │ └── cs-cloning.js │ ├── cs-visibility.min.js │ ├── cs-cloning.min.js │ ├── cs-visibility.js │ ├── cs-cloning.js │ └── cs.min.js └── css │ ├── cs-scan.min.css │ ├── cs-cloning.min.css │ ├── cs-scan.css │ ├── cs-cloning.css │ ├── cs-visibility.min.css │ ├── cs-visibility.css │ └── cs.min.css ├── languages ├── custom-sidebars-cs_CZ.mo ├── custom-sidebars-da_DK.mo ├── custom-sidebars-de_DE.mo ├── custom-sidebars-en_EN.mo ├── custom-sidebars-es_ES.mo ├── custom-sidebars-fr_FR.mo ├── custom-sidebars-he_IL.mo ├── custom-sidebars-hu_HU.mo ├── custom-sidebars-it_IT.mo ├── custom-sidebars-nl_BE.mo ├── custom-sidebars-nl_NL.mo ├── custom-sidebars-pl_PL.mo └── custom-sidebars-pt_BR.mo ├── views ├── widgets-delete.php ├── quick-edit.php ├── bulk-edit.php ├── widgets-export.php ├── col-sidebars.php ├── widgets-editor.php ├── metabox.php ├── widgets.php ├── widgets-location.php └── import.php ├── inc ├── integrations │ ├── class-custom-sidebars-integration.php │ ├── class-custom-sidebars-integration-wpml.php │ ├── class-custom-sidebars-integration-wml.php │ └── class-custom-sidebars-integration-polylang.php ├── class-custom-sidebars-widgets.php ├── class-custom-sidebars-checkup-notification.php ├── class-custom-sidebars-explain.php └── class-custom-sidebars-cloning.php ├── customsidebars.php ├── README.md └── license.txt /assets/img/devman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/assets/img/devman.png -------------------------------------------------------------------------------- /assets/img/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/assets/img/heart.png -------------------------------------------------------------------------------- /assets/img/stripes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/assets/img/stripes.png -------------------------------------------------------------------------------- /assets/img/hand-with-heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/assets/img/hand-with-heart.png -------------------------------------------------------------------------------- /assets/img/metabox/blogpage-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/assets/img/metabox/blogpage-info.png -------------------------------------------------------------------------------- /assets/img/metabox/wooshop-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/assets/img/metabox/wooshop-info.png -------------------------------------------------------------------------------- /languages/custom-sidebars-cs_CZ.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-cs_CZ.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-da_DK.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-da_DK.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-de_DE.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-de_DE.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-en_EN.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-en_EN.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-es_ES.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-es_ES.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-fr_FR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-fr_FR.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-he_IL.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-he_IL.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-hu_HU.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-hu_HU.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-it_IT.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-it_IT.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-nl_BE.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-nl_BE.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-nl_NL.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-nl_NL.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-pl_PL.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-pl_PL.mo -------------------------------------------------------------------------------- /languages/custom-sidebars-pt_BR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/languages/custom-sidebars-pt_BR.mo -------------------------------------------------------------------------------- /assets/img/metabox/frontpage-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/custom-sidebars/master/assets/img/metabox/frontpage-info.png -------------------------------------------------------------------------------- /assets/sass/_mixins.scss: -------------------------------------------------------------------------------- 1 | $red: #a00; 2 | 3 | @mixin border-radius($radius) { 4 | -webkit-border-radius: $radius; 5 | -moz-border-radius: $radius; 6 | -ms-border-radius: $radius; 7 | border-radius: $radius; 8 | } 9 | @mixin box-shadow($args) { 10 | -webkit-box-shadow: $args; 11 | -moz-box-shadow: $args; 12 | box-shadow: $args; 13 | } 14 | -------------------------------------------------------------------------------- /assets/js/src/metabox-allow-entry-author.js: -------------------------------------------------------------------------------- 1 | /*global jQuery:false */ 2 | /*global console:false */ 3 | /*global document:false */ 4 | /*global ajaxurl:false */ 5 | (function($){ 6 | jQuery(document).ready( function($) { 7 | $('#screen-options-wrap .cs-allow-author input[type=checkbox]').on( 'change', function() { 8 | var data = { 9 | 'action': 'custom_sidebars_allow_author', 10 | '_wpnonce': $('#custom_sidebars_allow_author').val(), 11 | 'value': this.checked 12 | }; 13 | $.post( ajaxurl, data ); 14 | }); 15 | }); 16 | })(jQuery); 17 | -------------------------------------------------------------------------------- /assets/css/cs-scan.min.css: -------------------------------------------------------------------------------- 1 | .custom-sidebars-wp-checkup{border-radius:4px;-ms-flex-align:center;align-items:center;background:#fff url(../img/heart.png) no-repeat 0 50%;border:0;display:-ms-flexbox;display:flex;min-height:100px;padding-left:135px;-ms-flex-pack:justify;justify-content:space-between}.custom-sidebars-wp-checkup form{white-space:nowrap}.custom-sidebars-wp-checkup form input{border:0;border-radius:4px}.custom-sidebars-wp-checkup form input[type=text]{background-color:#f2f2f2;padding:15px 14px}.custom-sidebars-wp-checkup form input[type=submit]{background-color:#17a8e3;color:#fff;padding:15px 35px;text-transform:uppercase;margin-left:10px}.custom-sidebars-wp-checkup p{font-size:1.2em}.custom-sidebars-wp-checkup p b{color:#840006} -------------------------------------------------------------------------------- /views/widgets-delete.php: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 |
11 | .', 'custom-sidebars' 13 | ); ?> 14 |
15 |
16 | 17 | 18 | 19 |
20 |
21 | -------------------------------------------------------------------------------- /assets/css/cs-cloning.min.css: -------------------------------------------------------------------------------- 1 | .inactive-sidebar .csb-clone{display:none}.widget-control-actions .csb-clone-button{margin:0 5px 0 0}.csb-marker{position:relative;box-shadow:0 0 0 1px rgba(0,0,0,.3)}.csb-marker .widget-inside,.csb-marker .widget-top{opacity:.5}.csb-marker:before{content:attr(data-group);position:absolute;top:50%;left:5px;right:5px;text-align:center;margin-top:-1em;line-height:2em;height:2em;font-size:20px;z-index:1001;background:rgba(255,255,255,.2)}.csb-marker:after{content:'';position:absolute;left:1px;top:1px;right:1px;bottom:1px;background:url(../img/stripes.png);opacity:.05;z-index:1000;cursor:default}h4.csb-group{padding-left:45px;position:relative}h4 .btn-clone-group{position:absolute;top:50%;margin-top:-10px;left:15px;cursor:pointer;opacity:.6}h4 .btn-clone-group:hover{opacity:1} -------------------------------------------------------------------------------- /assets/sass/cs-scan.scss: -------------------------------------------------------------------------------- 1 | @import 'mixins'; 2 | 3 | .custom-sidebars-wp-checkup { 4 | @include border-radius( 4px ); 5 | align-items: center; 6 | background: #fff url(../img/heart.png) no-repeat 0 50%; 7 | border: 0; 8 | display: flex; 9 | min-height: 100px; 10 | padding-left: 135px; 11 | justify-content: space-between; 12 | form { 13 | white-space: nowrap; 14 | input { 15 | border: 0; 16 | @include border-radius( 4px ); 17 | } 18 | input[type=text] { 19 | background-color: #f2f2f2; 20 | padding: 15px 14px; 21 | } 22 | input[type=submit] { 23 | background-color: #17a8e3; 24 | color: #fff; 25 | padding: 15px 35px; 26 | text-transform: uppercase; 27 | margin-left: 10px; 28 | } 29 | } 30 | p { 31 | font-size: 1.2em; 32 | b { 33 | color: #840006; 34 | } 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /assets/js/src/metabox-roles.js: -------------------------------------------------------------------------------- 1 | /*global jQuery:false */ 2 | /*global console:false */ 3 | /*global document:false */ 4 | /*global ajaxurl:false */ 5 | 6 | /** 7 | * Handle "Custom sidebars configuration is allowed for:" option on 8 | * widgets screen options. 9 | */ 10 | (function($){ 11 | jQuery(document).ready( function($) { 12 | $('#screen-options-wrap .cs-roles input[type=checkbox]').on( 'change', function() { 13 | var data = { 14 | 'action': 'custom_sidebars_metabox_roles', 15 | '_wpnonce': $('#custom_sidebars_metabox_roles').val(), 16 | 'fields': {} 17 | }; 18 | $('#screen-options-wrap .cs-roles input[type=checkbox]').each( function() { 19 | data.fields[$(this).val()] = this.checked; 20 | }); 21 | $.post( ajaxurl, data ); 22 | }); 23 | }); 24 | })(jQuery); 25 | -------------------------------------------------------------------------------- /assets/js/src/metabox-custom-taxonomies.js: -------------------------------------------------------------------------------- 1 | /*global jQuery:false */ 2 | /*global console:false */ 3 | /*global document:false */ 4 | /*global ajaxurl:false */ 5 | 6 | /** 7 | * Handle "Custom sidebars configuration is allowed for:" option on 8 | * widgets screen options. 9 | */ 10 | (function($){ 11 | jQuery(document).ready( function($) { 12 | $('#screen-options-wrap .cs-custom-taxonomies input[type=checkbox]').on( 'change', function() { 13 | var data = { 14 | 'action': 'custom_sidebars_metabox_custom_taxonomies', 15 | '_wpnonce': $('#custom_sidebars_custom_taxonomies').val(), 16 | 'fields': {} 17 | }; 18 | $('#screen-options-wrap .cs-custom-taxonomies input[type=checkbox]').each( function() { 19 | data.fields[$(this).val()] = this.checked; 20 | }); 21 | $.post( ajaxurl, data ); 22 | }); 23 | }); 24 | })(jQuery); 25 | -------------------------------------------------------------------------------- /assets/css/cs-scan.css: -------------------------------------------------------------------------------- 1 | .custom-sidebars-wp-checkup { 2 | border-radius: 4px; 3 | -ms-flex-align: center; 4 | align-items: center; 5 | background: #fff url(../img/heart.png) no-repeat 0 50%; 6 | border: 0; 7 | display: -ms-flexbox; 8 | display: flex; 9 | min-height: 100px; 10 | padding-left: 135px; 11 | -ms-flex-pack: justify; 12 | justify-content: space-between; 13 | } 14 | .custom-sidebars-wp-checkup form { 15 | white-space: nowrap; 16 | } 17 | .custom-sidebars-wp-checkup form input { 18 | border: 0; 19 | border-radius: 4px; 20 | } 21 | .custom-sidebars-wp-checkup form input[type=text] { 22 | background-color: #f2f2f2; 23 | padding: 15px 14px; 24 | } 25 | .custom-sidebars-wp-checkup form input[type=submit] { 26 | background-color: #17a8e3; 27 | color: #fff; 28 | padding: 15px 35px; 29 | text-transform: uppercase; 30 | margin-left: 10px; 31 | } 32 | .custom-sidebars-wp-checkup p { 33 | font-size: 1.2em; 34 | } 35 | .custom-sidebars-wp-checkup p b { 36 | color: #840006; 37 | } 38 | -------------------------------------------------------------------------------- /views/quick-edit.php: -------------------------------------------------------------------------------- 1 | 15 |
16 |
17 | 23 |
24 | 36 |
37 | 41 |
42 |
43 | -------------------------------------------------------------------------------- /assets/sass/cs-cloning.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS rules for the cloning module. 3 | */ 4 | 5 | .inactive-sidebar .csb-clone { 6 | display: none; 7 | } 8 | 9 | .widget-control-actions .csb-clone-button { 10 | margin: 0 5px 0 0; 11 | } 12 | 13 | .csb-marker { 14 | position: relative; 15 | box-shadow: 0 0 0px 1px rgba(0, 0, 0, 0.3); 16 | } 17 | .csb-marker .widget-top, 18 | .csb-marker .widget-inside { 19 | opacity: .5; 20 | } 21 | 22 | .csb-marker:before { 23 | content: attr(data-group); 24 | position: absolute; 25 | top: 50%; 26 | left: 5px; 27 | right: 5px; 28 | text-align: center; 29 | margin-top: -1em; 30 | line-height: 2em; 31 | height: 2em; 32 | font-size: 20px; 33 | z-index: 1001; 34 | background: rgba(255,255,255,.2); 35 | } 36 | 37 | .csb-marker:after { 38 | content: ''; 39 | position: absolute; 40 | left: 1px; 41 | top: 1px; 42 | right: 1px; 43 | bottom: 1px; 44 | background: url(../img/stripes.png); 45 | opacity: .05; 46 | z-index: 1000; 47 | cursor: default; 48 | } 49 | 50 | h4 { 51 | &.csb-group { 52 | padding-left: 45px; 53 | position: relative; 54 | } 55 | 56 | .btn-clone-group { 57 | position: absolute; 58 | top: 50%; 59 | margin-top: -10px; 60 | left: 15px; 61 | cursor: pointer; 62 | opacity: .6; 63 | 64 | &:hover { 65 | opacity: 1; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /assets/css/cs-cloning.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS rules for the cloning module. 3 | */ 4 | .inactive-sidebar .csb-clone { 5 | display: none; 6 | } 7 | 8 | .widget-control-actions .csb-clone-button { 9 | margin: 0 5px 0 0; 10 | } 11 | 12 | .csb-marker { 13 | position: relative; 14 | box-shadow: 0 0 0px 1px rgba(0, 0, 0, 0.3); 15 | } 16 | 17 | .csb-marker .widget-top, 18 | .csb-marker .widget-inside { 19 | opacity: .5; 20 | } 21 | 22 | .csb-marker:before { 23 | content: attr(data-group); 24 | position: absolute; 25 | top: 50%; 26 | left: 5px; 27 | right: 5px; 28 | text-align: center; 29 | margin-top: -1em; 30 | line-height: 2em; 31 | height: 2em; 32 | font-size: 20px; 33 | z-index: 1001; 34 | background: rgba(255, 255, 255, 0.2); 35 | } 36 | 37 | .csb-marker:after { 38 | content: ''; 39 | position: absolute; 40 | left: 1px; 41 | top: 1px; 42 | right: 1px; 43 | bottom: 1px; 44 | background: url(../img/stripes.png); 45 | opacity: .05; 46 | z-index: 1000; 47 | cursor: default; 48 | } 49 | 50 | h4.csb-group { 51 | padding-left: 45px; 52 | position: relative; 53 | } 54 | h4 .btn-clone-group { 55 | position: absolute; 56 | top: 50%; 57 | margin-top: -10px; 58 | left: 15px; 59 | cursor: pointer; 60 | opacity: .6; 61 | } 62 | h4 .btn-clone-group:hover { 63 | opacity: 1; 64 | } 65 | -------------------------------------------------------------------------------- /inc/integrations/class-custom-sidebars-integration.php: -------------------------------------------------------------------------------- 1 | key_name ] = array(); 32 | foreach ( $sidebars as $sb_id ) { 33 | if ( isset( $data[ $this->key_name ] ) ) { 34 | foreach ( $data[ $this->key_name ] as $sb_id => $value ) { 35 | if ( ! isset( $options[ $this->key_name ] ) ) { 36 | $options[ $this->key_name ] = array(); 37 | } 38 | foreach ( $value as $lang ) { 39 | $options[ $this->key_name ][ $lang ][ $sb_id ] = $id; 40 | } 41 | } 42 | } 43 | } 44 | return $options; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /views/bulk-edit.php: -------------------------------------------------------------------------------- 1 | 21 |
22 |
23 | 24 | 30 |
31 | 43 |
44 | 48 |
49 |
50 | -------------------------------------------------------------------------------- /assets/sass/_custom-sidebars-checkup.scss: -------------------------------------------------------------------------------- 1 | @import 'mixins'; 2 | 3 | .custom-sidebars-checkup { 4 | background-color: #fff; 5 | .cs-inner { 6 | background: url(../img/hand-with-heart.png) no-repeat 100% 100%; 7 | font-size: 1.2em; 8 | min-height: 227px; 9 | padding-bottom: 10px; 10 | h4, p { 11 | margin: 0; 12 | padding: 0 120px 0 30px; 13 | font-size: 1.1em; 14 | } 15 | h4 { 16 | color: #222; 17 | font-size: 1.2em; 18 | padding-top: 50px; 19 | } 20 | p { 21 | color: #c1272c; 22 | padding-top: 16px; 23 | } 24 | form { 25 | @include border-radius( 4px ); 26 | background-color: #fafafa; 27 | display: flex; 28 | flex-wrap: nowrap; 29 | justify-content: space-between; 30 | margin: 24px 30px 0 30px; 31 | padding: 0; 32 | input { 33 | background-color: transparent; 34 | border: 0; 35 | font-size: 1em; 36 | margin: 0; 37 | padding: 10px 15px; 38 | text-align: center; 39 | &[type=submit] { 40 | @include border-radius( 0 4px 4px 0 ); 41 | background-color: #00a7e6; 42 | color: #fff; 43 | min-width: 3em; 44 | text-transform: uppercase; 45 | } 46 | &[type=text] { 47 | color: #aaa; 48 | flex-grow: 1; 49 | &:active { 50 | @include box-shadow( none ); 51 | } 52 | } 53 | } 54 | } 55 | @media screen and (max-width: 590px) { 56 | form { 57 | background-color: transparent; 58 | display: block; 59 | input { 60 | &[type=text] { 61 | background-color: #fafafa; 62 | } 63 | &[type=submit] { 64 | @include border-radius( 4px ); 65 | display: block; 66 | margin: 10px 0 0 auto; 67 | width: auto; 68 | } 69 | } 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /views/widgets-export.php: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 |

11 |
12 | 13 |

14 | 15 | 21 |

22 |

23 |
24 | 25 |

26 |

27 | 30 |

31 | 32 |
33 |
34 |

35 |
36 | 37 |

38 | 39 | 40 |

41 |

42 | 45 |

46 | 47 |
48 |
49 | -------------------------------------------------------------------------------- /inc/class-custom-sidebars-widgets.php: -------------------------------------------------------------------------------- 1 | singleton. 27 | * 28 | * @since 2.0 29 | */ 30 | private function __construct() { 31 | if ( is_admin() ) { 32 | add_action( 33 | 'widgets_admin_page', 34 | array( $this, 'widget_sidebar_content' ) 35 | ); 36 | 37 | add_action( 38 | 'admin_head-widgets.php', 39 | array( $this, 'init_admin_head' ) 40 | ); 41 | } 42 | add_action( 'widgets_admin_page', array( $this, 'add_div_start' ) ); 43 | add_action( 'sidebar_admin_page', array( $this, 'add_div_end' ) ); 44 | } 45 | 46 | public function add_div_start() { 47 | echo '
'; 48 | } 49 | 50 | public function add_div_end() { 51 | echo '
'; 52 | } 53 | 54 | /** 55 | * Adds the additional HTML code to the widgets section. 56 | */ 57 | public function widget_sidebar_content() { 58 | if ( false === self::$accessibility_mode ) { 59 | include CSB_VIEWS_DIR . 'widgets.php'; 60 | } 61 | } 62 | 63 | /** 64 | * Initialize the admin-head for the widgets page. 65 | * 66 | * @since 2.0.9.7 67 | */ 68 | public function init_admin_head( $classes ) { 69 | add_filter( 70 | 'admin_body_class', 71 | array( $this, 'admin_body_class' ) 72 | ); 73 | } 74 | 75 | /** 76 | * Add a class to the body tag. 77 | * 78 | * @since 2.0.9.7 79 | */ 80 | public function admin_body_class( $classes ) { 81 | $classes .= ' no-auto-init '; 82 | return $classes; 83 | } 84 | }; 85 | -------------------------------------------------------------------------------- /views/col-sidebars.php: -------------------------------------------------------------------------------- 1 | %s', 37 | esc_html( $content ) 38 | ); 39 | } 40 | } 41 | /** 42 | * prepare 43 | */ 44 | if ( $is_front ) { 45 | custom_sidebars_col_sideber_not_available( __( 'Home Page', 'custom-sidebars' ) ); 46 | } elseif ( $is_blog ) { 47 | custom_sidebars_col_sideber_not_available( __( 'Blog Page', 'custom-sidebars' ) ); 48 | } else if ( $is_woo_shop ) { 49 | custom_sidebars_col_sideber_not_available( __( 'WooCommerce Shop', 'custom-sidebars' ) ); 50 | } else { 51 | global $wp_registered_sidebars; 52 | $available = CustomSidebars::sort_sidebars_by_name( $wp_registered_sidebars ); 53 | $content = ''; 54 | foreach ( $sidebars as $s ) { 55 | $sb_name = $available[ $s ]['name']; 56 | $replaced = ! empty( $available[ $selected[ $s ] ] ); 57 | $class = $replaced ? 'cust' : 'def'; 58 | 59 | if ( $replaced ) { 60 | $content .= sprintf( 61 | '
', 62 | esc_attr( $s ), 63 | isset( $selected[ $s ] )? esc_attr( $selected[ $s ] ):'', 64 | esc_attr( $class, 'custom-sidebars' ) 65 | ); 66 | $content .= esc_html( $sb_name ); 67 | $content .= '
'; 68 | $content .= '
'; 69 | $content .= esc_html( $available[ $selected[ $s ] ]['name'] ); 70 | $content .= '
'; 71 | } 72 | } 73 | if ( empty( $content ) ) { 74 | echo '-'; 75 | } else { 76 | echo '
'; 77 | echo $content; 78 | echo '
'; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /assets/css/cs-visibility.min.css: -------------------------------------------------------------------------------- 1 | .inactive-sidebar .csb-visibility{display:none}.widget-control-actions .button{margin:0 0 0 5px}@media screen and (max-width:782px){.widget-control-actions .csb-visibility-button .dashicons{line-height:normal;height:auto;font-size:19px}}@media screen and (max-width:782px) and (max-width:400px){.widget-control-actions .csb-visibility-button .dashicons{display:none}}@media screen and (max-width:782px){.widget-control-actions .alignleft,.widget-control-actions .alignright{float:none}.widget-control-actions .alignright{padding-top:10px;text-align:right}.widget-control-actions .alignright .button{margin-bottom:5px}}.csb-visibility{margin:0 -15px 15px}.csb-option-row{margin:0 -15px;padding:0 15px 12px;position:relative}.csb-visibility-inner{border:1px solid #e5e5e5;border-left:0;border-right:0;padding:12px 15px 0;background:#fafafa}.csb-visibility-inner .toggle-action{display:block;margin:-15px -15px 0;padding:15px 15px 0;cursor:pointer;border:0}.csb-visibility-inner .csb-option-row:hover{background:#f4f4f4}.csb-visibility-inner .csb-option-row:hover.csb-always:hover{background:0 0}.csb-visibility-inner .csb-option-row.csb-action .action{top:15px}.csb-visibility-inner .csb-option-row .clear-filter:hover{color:#c00}.csb-visibility-inner .csb-option-row .action{position:absolute;right:15px;top:7px;z-index:1;color:#aaa;cursor:pointer;font-size:20px}.csb-visibility-inner .csb-option-row .action:hover{color:#000}.csb-visibility-inner .csb-action{margin-bottom:0}.csb-visibility-inner .csb-action label{cursor:default}.csb-visibility-inner .csb-action b{padding:5px;border:1px solid transparent;cursor:pointer;margin-left:-6px}.csb-visibility-inner .csb-action:hover b{padding:5px;background:#fff;border:1px solid #ddd}.csb-visibility-inner .csb-always{padding-bottom:0;text-align:center;font-style:italic}.csb-visibility-inner .csb-always label{margin-bottom:0;color:#aaa;cursor:default}.csb-visibility-inner .csb-and{margin-right:10px;font-weight:700}.csb-visibility-inner label{display:block;border-top:1px solid #e8e8e8;margin:0 -15px 5px;padding:5px 15px}.csb-visibility-inner .csb-detail-row label{border:0;margin-bottom:0;padding-bottom:0}.csb-visibility-inner .csb-detail-row .detail{margin-top:10px}.csb-visibility-inner .chosen-container{display:block!important;width:100%!important}.csb-visibility-inner .dropdown{position:absolute;z-index:2;background:#fff;border:1px solid #ddd;right:10px;top:20px;color:#555;box-shadow:0 1px 10px rgba(0,0,0,.15)}.csb-visibility-inner .dropdown li{padding:5px 15px;cursor:pointer;margin:0}.csb-visibility-inner .dropdown li:hover{color:#000;background:#eee}.csb-visibility-inner .dropdown li.csb-group,.csb-visibility-inner .dropdown li.csb-group:hover{color:#999;font-weight:700;background:#f8f8f8;padding-left:5px;cursor:default} -------------------------------------------------------------------------------- /assets/js/cs-visibility.min.js: -------------------------------------------------------------------------------- 1 | /*! Custom Sidebars - v3.2.3 2 | * https://premium.wpmudev.org/project/custom-sidebars-pro/ 3 | * Copyright (c) 2019; * Licensed GPLv2+ */ 4 | 5 | jQuery(function(){var a=jQuery(document),b=function(a){var b=jQuery(this),c=b.closest(".csb-option-row"),d=b.closest(".widget"),e="."+jQuery.trim(c.attr("class").replace("csb-option-row","")),f=d.find('[data-for="'+e+'"]'),g=c.find("input, select, textarea");return a.preventDefault(),f.show(),c.fadeOut(400,function(){g.val("").trigger("change.select2"),d.trigger("csb:update")}),!1},c=function(a){jQuery(".csb-action .dropdown:visible").hide()},d=function(a){var b=jQuery(this),d=b.data("for"),e=b.closest(".widget"),f=e.find(".csb-always"),g=e.find(d);return a.preventDefault(),g.show(),b.hide(),f.hide(),c(),e.trigger("csb:update"),!1},e=function(){var a=jQuery(this).closest(".widget"),b=a.find(".csb-always"),c=a.find(".csb-option-row:visible:not(.csb-action,.csb-always)");0===c.length?b.show():(b.hide(),c.find(".csb-and").show(),c.first().find(".csb-and").hide()),wpmUi.upgrade_multiselect(a)},f=function(b){var d=jQuery(this),e=d.closest(".csb-option-row"),f=e.find(".dropdown");return b.preventDefault(),f.show(),a.one("click",c),!1},g=function(a){var b=jQuery(this),c=b.closest(".widget"),d=c.find(".csb-visibility-inner"),e=d.find(".csb-visible-flag");return a.preventDefault(),"0"===e.val()?(e.val("1"),d.show(),c.trigger("csb:update")):(e.val("0"),d.hide()),!1},h=function(a){var b=jQuery(this).closest("label"),c=b.closest(".widget"),d="#"+b.attr("for"),e=c.find(d),f=e.val(),g=c.find(".lbl-show-if"),h=c.find(".lbl-hide-if");return a.preventDefault(),"show"!==f?(g.show(),h.hide(),e.val("show")):(g.hide(),h.show(),e.val("hide")),!1},i=function(a){var b=jQuery(this).closest("label"),c=b.closest(".csb-detail-row"),d=b.find("input[type=checkbox]"),e=b.find(".lbl"),f=c.find(".detail"),g=f.find("input,select,textarea");d.prop("checked")?(e.text(d.data("lbl-single")),f.show()):(e.text(d.data("lbl-all")),f.hide(),g.val("").trigger("change.select2"))},j=function(a){var b,c=jQuery(this),d=c.closest(".csb-option-row"),e=d.find(".csb-detail-row"),f=c.val();if(e.addClass("csb-hide"),f)for(b=0;b 8 | 9 |
10 | 11 | 12 | 13 |
14 |
15 | 16 | 17 |
18 |
19 |
20 | 21 | 22 |
23 |
24 |
25 |
26 |
27 | 28 | Justin ' . 32 | 'Tadlock Blog. Do not use these fields if you are not sure what you are doing, it can break ' . 33 | 'the design of your site. Leave these fields blank to use the theme sidebars design.', 'custom-sidebars' 34 | ); ?> 35 |
36 |
37 |
38 |
39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |
48 |
49 | 50 | 51 |
52 |
53 | 54 | 55 |
56 |
57 |
58 | 62 | 63 | 64 | 65 |
66 |
67 | -------------------------------------------------------------------------------- /inc/integrations/class-custom-sidebars-integration-wpml.php: -------------------------------------------------------------------------------- 1 | singleton. 26 | * 27 | * @since 3.1.2 28 | */ 29 | private function __construct() { 30 | $languages = apply_filters( 'wpml_active_languages', array() ); 31 | if ( empty( $languages ) ) { 32 | return; 33 | } 34 | $this->key_name = 'wpml'; 35 | $this->languages = $languages; 36 | add_filter( 'custom_sidebars_integrations', array( $this, 'prepare' ) ); 37 | add_filter( 'custom_sidebars_get_location', array( $this, 'get_location' ), 10, 2 ); 38 | add_filter( 'custom_sidebars_set_location', array( $this, 'set_location' ), 10, 4 ); 39 | add_filter( 'cs_replace_sidebars', array( $this, 'replace' ), 10, 2 ); 40 | } 41 | 42 | /** 43 | * Save dismiss decision, no more show it. 44 | * 45 | * @since 3.1.2 46 | */ 47 | public function prepare( $tabs ) { 48 | $tabs[ $this->key_name ] = array( 49 | 'title' => __( 'WPML', 'custom-sidebars' ), 50 | 'cat_name' => __( 'Language', 'custom-sidebars' ), 51 | ); 52 | return $tabs; 53 | } 54 | 55 | /** 56 | * Add languages 57 | * 58 | * @since 3.1.2 59 | */ 60 | public function get_location( $req, $defaults ) { 61 | $req->wpml = array(); 62 | foreach ( $this->languages as $key => $lang ) { 63 | $req->wpml[ $key ] = array( 64 | 'name' => isset( $lang['translated_name'] )? $lang['translated_name']:$key, 65 | 'native' => isset( $lang['native_name'] )? $lang['native_name'] : '', 66 | 'archive' => array(), 67 | ); 68 | if ( 69 | isset( $defaults[ $this->key_name ] ) 70 | && isset( $defaults[ $this->key_name ][ $key ] ) 71 | ) { 72 | $req->wpml[ $key ]['archive'] = $defaults[ $this->key_name ][ $key ]; 73 | } 74 | } 75 | return $req; 76 | } 77 | 78 | /** 79 | * Replace sidebar 80 | * 81 | * @since 3.1.2 82 | */ 83 | public function replace( $replacements, $options ) { 84 | if ( ! isset( $options[ $this->key_name ] ) ) { 85 | return $replacements; 86 | } 87 | $current_language = apply_filters( 'wpml_current_language', null ); 88 | if ( empty( $current_language ) ) { 89 | return $replacements; 90 | } 91 | foreach ( $replacements as $sb_id => $replacement ) { 92 | if ( ! empty( $replacement ) ) { 93 | continue; 94 | } 95 | if ( 96 | isset( $options[ $this->key_name ][ $current_language ] ) 97 | && isset( $options[ $this->key_name ][ $current_language ][ $sb_id ] ) 98 | ) { 99 | $replacements[ $sb_id ] = array( 100 | $options[ $this->key_name ][ $current_language ][ $sb_id ], 101 | $this->key_name, 102 | $current_language, 103 | ); 104 | } 105 | } 106 | return $replacements; 107 | } 108 | }; 109 | -------------------------------------------------------------------------------- /inc/integrations/class-custom-sidebars-integration-wml.php: -------------------------------------------------------------------------------- 1 | singleton. 26 | * 27 | * @since 3.2.0 28 | */ 29 | private function __construct() { 30 | if ( ! function_exists( 'wpm_get_languages' ) ) { 31 | return; 32 | } 33 | $languages = wpm_get_languages(); 34 | if ( empty( $languages ) ) { 35 | return; 36 | } 37 | $this->key_name = 'wml'; 38 | $this->languages = $languages; 39 | add_filter( 'custom_sidebars_integrations', array( $this, 'prepare' ) ); 40 | add_filter( 'custom_sidebars_get_location', array( $this, 'get_location' ), 10, 2 ); 41 | add_filter( 'custom_sidebars_set_location', array( $this, 'set_location' ), 10, 4 ); 42 | add_filter( 'cs_replace_sidebars', array( $this, 'replace' ), 10, 2 ); 43 | } 44 | 45 | /** 46 | * Save dismiss decision, no more show it. 47 | * 48 | * @since 3.2.0 49 | */ 50 | public function prepare( $tabs ) { 51 | $tabs[ $this->key_name ] = array( 52 | 'title' => __( 'WP Multilang', 'custom-sidebars' ), 53 | 'cat_name' => __( 'Language', 'custom-sidebars' ), 54 | ); 55 | return $tabs; 56 | } 57 | 58 | /** 59 | * Add languages 60 | * 61 | * @since 3.2.0 62 | */ 63 | public function get_location( $req, $defaults ) { 64 | $req->wml = array(); 65 | foreach ( $this->languages as $key => $lang ) { 66 | $req->wml[ $key ] = array( 67 | 'name' => isset( $lang['name'] )? $lang['name'] : '', 68 | 'native' => isset( $lang['name'] )? $lang['name'] : '', 69 | 'archive' => array(), 70 | ); 71 | if ( 72 | isset( $defaults[ $this->key_name ] ) 73 | && isset( $defaults[ $this->key_name ][ $key ] ) 74 | ) { 75 | $req->wml[ $key ]['archive'] = $defaults[ $this->key_name ][ $key ]; 76 | } 77 | } 78 | return $req; 79 | } 80 | 81 | /** 82 | * Replace sidebar 83 | * 84 | * @since 3.2.0 85 | */ 86 | public function replace( $replacements, $options ) { 87 | if ( ! isset( $options[ $this->key_name ] ) ) { 88 | return $replacements; 89 | } 90 | if ( ! function_exists( 'wpm_get_language' ) ) { 91 | return; 92 | } 93 | $current_language = wpm_get_language(); 94 | if ( empty( $current_language ) ) { 95 | return $replacements; 96 | } 97 | foreach ( $replacements as $sb_id => $replacement ) { 98 | if ( ! empty( $replacement ) ) { 99 | continue; 100 | } 101 | if ( 102 | isset( $options[ $this->key_name ][ $current_language ] ) 103 | && isset( $options[ $this->key_name ][ $current_language ][ $sb_id ] ) 104 | ) { 105 | $replacements[ $sb_id ] = array( 106 | $options[ $this->key_name ][ $current_language ][ $sb_id ], 107 | $this->key_name, 108 | $current_language, 109 | ); 110 | } 111 | } 112 | return $replacements; 113 | } 114 | }; 115 | -------------------------------------------------------------------------------- /assets/sass/cs-visibility.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS rules for the visibility module. 3 | */ 4 | 5 | .inactive-sidebar .csb-visibility { 6 | display: none; 7 | } 8 | 9 | .widget-control-actions { 10 | .button { 11 | margin: 0 0 0 5px; 12 | } 13 | .csb-visibility-button { 14 | @media screen and (max-width: 782px) { 15 | .dashicons { 16 | line-height: normal; 17 | height: auto; 18 | font-size: 19px; 19 | @media screen and (max-width: 400px) { 20 | display: none; 21 | } 22 | } 23 | } 24 | } 25 | @media screen and (max-width: 782px) { 26 | .alignright, 27 | .alignleft { 28 | float: none; 29 | } 30 | .alignright { 31 | padding-top: 10px; 32 | text-align: right; 33 | .button { 34 | margin-bottom: 5px; 35 | } 36 | } 37 | } 38 | } 39 | 40 | .csb-visibility { 41 | margin: 0 -15px 15px; 42 | } 43 | 44 | .csb-option-row { 45 | margin: 0 -15px; 46 | padding: 0 15px 12px; 47 | position: relative; 48 | } 49 | 50 | .csb-visibility-inner { 51 | border: 1px solid #E5E5E5; 52 | border-left: 0; 53 | border-right: 0; 54 | padding: 12px 15px 0; 55 | background: #FAFAFA; 56 | 57 | .toggle-action { 58 | display: block; 59 | margin: -15px -15px 0; 60 | padding: 15px 15px 0; 61 | cursor: pointer; 62 | border: 0; 63 | /*color: #0074A2;*/ 64 | } 65 | 66 | .csb-option-row { 67 | &:hover { 68 | background: #F4F4F4; 69 | &.csb-always { 70 | &:hover { 71 | background: transparent; 72 | } 73 | } 74 | } 75 | &.csb-action { 76 | .action { 77 | top: 15px; 78 | } 79 | } 80 | .clear-filter { 81 | &:hover { 82 | color: #C00; 83 | } 84 | } 85 | .action { 86 | position: absolute; 87 | right: 15px; 88 | top: 7px; 89 | z-index: 1; 90 | color: #AAA; 91 | cursor: pointer; 92 | font-size: 20px; 93 | &:hover { 94 | color: #000; 95 | } 96 | } 97 | } 98 | 99 | .csb-action { 100 | margin-bottom: 0; 101 | label { 102 | cursor: default; 103 | } 104 | b { 105 | padding: 5px; 106 | border: 1px solid transparent; 107 | cursor: pointer; 108 | margin-left: -6px; 109 | } 110 | &:hover b { 111 | padding: 5px; 112 | background: #FFF; 113 | border: 1px solid #DDD; 114 | } 115 | } 116 | 117 | .csb-always { 118 | padding-bottom: 0; 119 | text-align: center; 120 | font-style: italic; 121 | label { 122 | margin-bottom: 0; 123 | color: #AAA; 124 | cursor: default; 125 | } 126 | } 127 | 128 | .csb-and { 129 | margin-right: 10px; 130 | font-weight: bold; 131 | } 132 | 133 | label { 134 | display: block; 135 | border-top: 1px solid #E8E8E8; 136 | margin: 0 -15px 5px; 137 | padding: 5px 15px; 138 | } 139 | 140 | .csb-detail-row { 141 | label { 142 | border: 0; 143 | margin-bottom: 0; 144 | padding-bottom: 0; 145 | } 146 | .detail { 147 | margin-top: 10px; 148 | } 149 | } 150 | 151 | .chosen-container { 152 | display: block !important; 153 | width: 100% !important; 154 | } 155 | 156 | .dropdown { 157 | position: absolute; 158 | z-index: 2; 159 | background: #FFF; 160 | border: 1px solid #DDD; 161 | right: 10px; 162 | top: 20px; 163 | color: #555; 164 | box-shadow: 0 1px 10px rgba(0,0,0,0.15); 165 | li { 166 | padding: 5px 15px; 167 | cursor: pointer; 168 | margin: 0; 169 | &:hover { 170 | color: #000; 171 | background: #EEE; 172 | } 173 | &.csb-group, 174 | &.csb-group:hover { 175 | color: #999; 176 | font-weight: bold; 177 | background: #F8F8F8; 178 | padding-left: 5px; 179 | cursor: default; 180 | } 181 | } 182 | } 183 | 184 | } 185 | -------------------------------------------------------------------------------- /inc/integrations/class-custom-sidebars-integration-polylang.php: -------------------------------------------------------------------------------- 1 | singleton. 26 | * 27 | * @since 3.1.2 28 | */ 29 | private function __construct() { 30 | if ( ! defined( 'POLYLANG_VERSION' ) ) { 31 | return; 32 | } 33 | $this->key_name = 'polylang'; 34 | add_filter( 'custom_sidebars_integrations', array( $this, 'prepare' ) ); 35 | add_filter( 'custom_sidebars_get_location', array( $this, 'get_location' ), 10, 2 ); 36 | add_filter( 'custom_sidebars_set_location', array( $this, 'set_location' ), 10, 4 ); 37 | add_filter( 'cs_replace_sidebars', array( $this, 'replace' ), 10, 2 ); 38 | } 39 | 40 | private function check() { 41 | if ( ! function_exists( 'pll_the_languages' ) ) { 42 | return false; 43 | } 44 | if ( ! empty( $this->languages ) ) { 45 | return true; 46 | } 47 | $args = array( 48 | 'raw' => true, 49 | 'hide_if_empty' => false, 50 | ); 51 | $languages = pll_the_languages( $args ); 52 | if ( empty( $languages ) ) { 53 | return false; 54 | } 55 | $this->languages = $languages; 56 | return true; 57 | } 58 | 59 | /** 60 | * Save dismiss decision, no more show it. 61 | * 62 | * @since 3.1.2 63 | */ 64 | public function prepare( $tabs ) { 65 | $tabs[ $this->key_name ] = array( 66 | 'title' => __( 'Polylang', 'custom-sidebars' ), 67 | 'cat_name' => __( 'Language', 'custom-sidebars' ), 68 | ); 69 | return $tabs; 70 | } 71 | 72 | /** 73 | * Add languages 74 | * 75 | * @since 3.1.2 76 | */ 77 | public function get_location( $req, $defaults ) { 78 | $check = $this->check(); 79 | if ( ! $check ) { 80 | return $req; 81 | } 82 | $req->polylang = array(); 83 | foreach ( $this->languages as $key => $lang ) { 84 | $req->polylang[ $key ] = array( 85 | 'name' => $lang['name'], 86 | 'archive' => array(), 87 | ); 88 | if ( 89 | isset( $defaults[ $this->key_name ] ) 90 | && isset( $defaults[ $this->key_name ][ $key ] ) 91 | ) { 92 | $req->polylang[ $key ]['archive'] = $defaults[ $this->key_name ][ $key ]; 93 | } 94 | } 95 | return $req; 96 | } 97 | 98 | /** 99 | * Replace sidebar 100 | * 101 | * @since 3.1.2 102 | */ 103 | public function replace( $replacements, $options ) { 104 | $check = $this->check(); 105 | if ( ! $check ) { 106 | return $replacements; 107 | } 108 | if ( ! isset( $options[ $this->key_name ] ) ) { 109 | return $replacements; 110 | } 111 | if ( ! function_exists( 'pll_current_language' ) ) { 112 | return $replacements; 113 | } 114 | $current_language = pll_current_language(); 115 | if ( empty( $current_language ) ) { 116 | return $replacements; 117 | } 118 | foreach ( $replacements as $sb_id => $replacement ) { 119 | if ( ! empty( $replacement ) ) { 120 | continue; 121 | } 122 | if ( 123 | isset( $options[ $this->key_name ][ $current_language ] ) 124 | && isset( $options[ $this->key_name ][ $current_language ][ $sb_id ] ) 125 | ) { 126 | $replacements[ $sb_id ] = array( 127 | $options[ $this->key_name ][ $current_language ][ $sb_id ], 128 | $this->key_name, 129 | $current_language, 130 | ); 131 | } 132 | } 133 | return $replacements; 134 | } 135 | }; 136 | -------------------------------------------------------------------------------- /assets/css/cs-visibility.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS rules for the visibility module. 3 | */ 4 | .inactive-sidebar .csb-visibility { 5 | display: none; 6 | } 7 | 8 | .widget-control-actions .button { 9 | margin: 0 0 0 5px; 10 | } 11 | @media screen and (max-width: 782px) { 12 | .widget-control-actions .csb-visibility-button .dashicons { 13 | line-height: normal; 14 | height: auto; 15 | font-size: 19px; 16 | } 17 | } 18 | @media screen and (max-width: 782px) and (max-width: 400px) { 19 | .widget-control-actions .csb-visibility-button .dashicons { 20 | display: none; 21 | } 22 | } 23 | 24 | @media screen and (max-width: 782px) { 25 | .widget-control-actions .alignright, 26 | .widget-control-actions .alignleft { 27 | float: none; 28 | } 29 | .widget-control-actions .alignright { 30 | padding-top: 10px; 31 | text-align: right; 32 | } 33 | .widget-control-actions .alignright .button { 34 | margin-bottom: 5px; 35 | } 36 | } 37 | 38 | .csb-visibility { 39 | margin: 0 -15px 15px; 40 | } 41 | 42 | .csb-option-row { 43 | margin: 0 -15px; 44 | padding: 0 15px 12px; 45 | position: relative; 46 | } 47 | 48 | .csb-visibility-inner { 49 | border: 1px solid #E5E5E5; 50 | border-left: 0; 51 | border-right: 0; 52 | padding: 12px 15px 0; 53 | background: #FAFAFA; 54 | } 55 | .csb-visibility-inner .toggle-action { 56 | display: block; 57 | margin: -15px -15px 0; 58 | padding: 15px 15px 0; 59 | cursor: pointer; 60 | border: 0; 61 | /*color: #0074A2;*/ 62 | } 63 | .csb-visibility-inner .csb-option-row:hover { 64 | background: #F4F4F4; 65 | } 66 | .csb-visibility-inner .csb-option-row:hover.csb-always:hover { 67 | background: transparent; 68 | } 69 | .csb-visibility-inner .csb-option-row.csb-action .action { 70 | top: 15px; 71 | } 72 | .csb-visibility-inner .csb-option-row .clear-filter:hover { 73 | color: #C00; 74 | } 75 | .csb-visibility-inner .csb-option-row .action { 76 | position: absolute; 77 | right: 15px; 78 | top: 7px; 79 | z-index: 1; 80 | color: #AAA; 81 | cursor: pointer; 82 | font-size: 20px; 83 | } 84 | .csb-visibility-inner .csb-option-row .action:hover { 85 | color: #000; 86 | } 87 | .csb-visibility-inner .csb-action { 88 | margin-bottom: 0; 89 | } 90 | .csb-visibility-inner .csb-action label { 91 | cursor: default; 92 | } 93 | .csb-visibility-inner .csb-action b { 94 | padding: 5px; 95 | border: 1px solid transparent; 96 | cursor: pointer; 97 | margin-left: -6px; 98 | } 99 | .csb-visibility-inner .csb-action:hover b { 100 | padding: 5px; 101 | background: #FFF; 102 | border: 1px solid #DDD; 103 | } 104 | .csb-visibility-inner .csb-always { 105 | padding-bottom: 0; 106 | text-align: center; 107 | font-style: italic; 108 | } 109 | .csb-visibility-inner .csb-always label { 110 | margin-bottom: 0; 111 | color: #AAA; 112 | cursor: default; 113 | } 114 | .csb-visibility-inner .csb-and { 115 | margin-right: 10px; 116 | font-weight: bold; 117 | } 118 | .csb-visibility-inner label { 119 | display: block; 120 | border-top: 1px solid #E8E8E8; 121 | margin: 0 -15px 5px; 122 | padding: 5px 15px; 123 | } 124 | .csb-visibility-inner .csb-detail-row label { 125 | border: 0; 126 | margin-bottom: 0; 127 | padding-bottom: 0; 128 | } 129 | .csb-visibility-inner .csb-detail-row .detail { 130 | margin-top: 10px; 131 | } 132 | .csb-visibility-inner .chosen-container { 133 | display: block !important; 134 | width: 100% !important; 135 | } 136 | .csb-visibility-inner .dropdown { 137 | position: absolute; 138 | z-index: 2; 139 | background: #FFF; 140 | border: 1px solid #DDD; 141 | right: 10px; 142 | top: 20px; 143 | color: #555; 144 | box-shadow: 0 1px 10px rgba(0, 0, 0, 0.15); 145 | } 146 | .csb-visibility-inner .dropdown li { 147 | padding: 5px 15px; 148 | cursor: pointer; 149 | margin: 0; 150 | } 151 | .csb-visibility-inner .dropdown li:hover { 152 | color: #000; 153 | background: #EEE; 154 | } 155 | .csb-visibility-inner .dropdown li.csb-group, .csb-visibility-inner .dropdown li.csb-group:hover { 156 | color: #999; 157 | font-weight: bold; 158 | background: #F8F8F8; 159 | padding-left: 5px; 160 | cursor: default; 161 | } 162 | -------------------------------------------------------------------------------- /assets/js/cs-cloning.min.js: -------------------------------------------------------------------------------- 1 | /*! Custom Sidebars - v3.2.3 2 | * https://premium.wpmudev.org/project/custom-sidebars-pro/ 3 | * Copyright (c) 2019; * Licensed GPLv2+ */ 4 | 5 | jQuery(function(){var a=jQuery(document),b=jQuery("#widgets-right"),c=!1,d=function(){for(var a=jQuery("#widgets-left input.csb-clone-group"),c=parseInt(a.first().val());b.find('input.csb-clone-group[value="'+c+'"]').length;)c+=1;a.val(c)},e=function(a){var b=jQuery(this).closest(".widget"),e=jQuery("#widgets-left"),f=jQuery(".widgets-chooser"),g=jQuery("#wpbody-content");a.preventDefault(),c=!0,"new"===b.find("input.csb-clone-state").val()&&window.wpWidgets.save(b,0,0,0),window.wpWidgets.clearWidgetSelection(),f.slideUp(200,function(){f.hide(),g.append(this)});var h=b.find("input.id_base").val(),i=e.find('input.id_base[value="'+h+'"]'),j=i.closest(".widget");j.addClass("widget-in-question");var k=b.find("input.csb-clone-group").val(),l=(j.find(".widget-control-actions"),j.find("input.csb-clone-group")),m=j.find("input.csb-clone-state");l.val(k),m.val("empty");var n=b.closest(".widgets-sortables"),o=n.attr("id");return f.find(".widgets-chooser-selected").removeClass("widgets-chooser-selected"),f.find("li").each(function(){var a=jQuery(this);o===a.data("sidebarId")&&a.addClass("widgets-chooser-selected").focus()}),window.wpWidgets.addWidget(f),window.wpWidgets.clearWidgetSelection(),d(),c=!1,!1},f=function(a){var c=jQuery(this).closest(".widget"),d=c.find("input.csb-clone-group").val();b.find('input.csb-clone-group[value="'+d+'"]').closest(".widget").not(c).each(function(){var a=jQuery(this);a.find("input.csb-clone-state"),a.addClass("wpmui-loading").attr("data-reload",!0)})},g=function(a,b){var c=jQuery(b).closest(".widget"),d=c.find(".csb-clone-button"),g=c.find(".widget-control-actions .widget-control-save"),h=c.find(".widget-control-actions .spinner"),i=c.find(".widget-control-save");c.data("_csb_cloning")||(h.insertBefore(g).css({float:"left"}),d.insertBefore(g).click(e),i.click(f),c.data("_csb_cloning",!0))},h=function(a,e){if(c)return!1;for(var f=jQuery(e).closest(".widget"),g=f.find("input.csb-clone-group"),h=parseInt(g.val()),i=null;;){if(i=b.find('input.csb-clone-group[value="'+h+'"]'),!i.length||1===i.length&&i[0]===g[0])break;h+=1}g.val(h),d()},i=function(a){var c=jQuery(this).closest(".widget"),d=c.find("input.csb-clone-group").val(),e=b.find('input.csb-clone-group[value="'+d+'"]').closest(".widget");isNaN(d)||d<1||(e.addClass("csb-marker"),c.removeClass("csb-marker"))},j=function(a){jQuery(".widget.csb-marker").removeClass("csb-marker")},k=function(a){var b=jQuery(this).closest(".widget"),c=b.find(".widget-title h4"),d=c.find(".btn-clone-group"),e=b.find("input.csb-clone-group");return a.preventDefault(),a.stopPropagation(),c.hasClass("group-active")?(c.removeClass("group-active"),d.removeClass("dashicons-admin-links").addClass("dashicons-editor-unlink"),e.data("group",e.val()),e.val(0),j()):(c.addClass("group-active"),d.addClass("dashicons-admin-links").removeClass("dashicons-editor-unlink"),e.val(e.data("group")),i.call(this,[a])),!1},l=function(){b.find("input.csb-clone-group").each(function(){var a=jQuery(this).val(),c=b.find('input.csb-clone-group[value="'+a+'"]').closest(".widget"),d=c.find(".widget-title h4, .widget-title h3"),e="add";(isNaN(a)||a<1)&&(e="remove"),c.length<2&&(e="remove"),d.removeClass("csb-group group-active").find(".btn-clone-group").remove(),c.removeAttr("data-csb-icon"),"add"===e&&(d.addClass("csb-group group-active").prepend(' '),d.find(".btn-clone-group").hover(i,j).click(k))})},m=function(a){"empty"===a.find("input.csb-clone-state").val()&&(a.addClass("wpmui-loading"),window.wpWidgets.save(a,0,1,0))},n=function(a){b.find(".widget[data-reload]").each(function(){var a=jQuery(this);a.find("input.csb-clone-state").val("empty"),a.removeAttr("data-reload"),window.wpWidgets.save(a,0,0,0)})},o=function(a,b,c,d){var e="string"==typeof c.data?c.data:"",f=e.match(/^.*&action=([^&]+).*$/),g=e.match(/^.*&widget-id=([^&]+).*$/),h=f&&2===f.length?f[1]:"",i=g&&2===g.length?g[1]:"";if(i.length){var j=jQuery('.widget input.widget-id[value="'+i+'"]'),k=j.closest(".widget");switch(h){case"save-widget":k.removeClass("wpmui-loading"),d.length?d.match(/^deleted:/)?window.setTimeout(l,400):(l(),n()):m(k)}}};b.find(".widget").each(g),a.on("widget-added",g),a.on("widget-added",h),a.ajaxSuccess(o),l(),d()}); -------------------------------------------------------------------------------- /views/metabox.php: -------------------------------------------------------------------------------- 1 | '; 32 | printf( 33 | '%s', 34 | sprintf( 35 | esc_html__( 'To change the sidebar for %s', 'custom-sidebars' ), 36 | $page_name 37 | ) 38 | ); 39 | echo ''; 63 | echo '

'; 64 | $url = esc_url( CSB_IMG_URL . 'metabox/' . $img . '?version=PLUGIN_VERSION' ); 65 | printf( 66 | '', 67 | esc_url( $url ), 68 | esc_url( $url ) 69 | ); 70 | } 71 | } 72 | /** 73 | * show 74 | */ 75 | if ( $is_front ) { 76 | $page_name = esc_html__( 'Front Page', 'custom-sidebars' ); 77 | custom_sidebars_replace_not_allowed( $page_name, 'frontpage-info.png' ); 78 | } elseif ( $is_blog ) { 79 | $page_name = esc_html__( 'Blog Page', 'custom-sidebars' ); 80 | $archive = esc_html__( 'Post Index', 'custom-sidebars' ); 81 | custom_sidebars_replace_not_allowed( $page_name, 'blogpage-info.png', $archive ); 82 | } elseif ( $is_woo_shop ) { 83 | $page_name = esc_html__( 'WooCommerce Shop', 'custom-sidebars' ); 84 | $post_type_object = get_post_type_object( 'product' ); 85 | $archive = sprintf( esc_html__( '%s Archives', 'custom-sidebars' ), $post_type_object->label ); 86 | custom_sidebars_replace_not_allowed( $page_name, 'wooshop-info.png', $archive ); 87 | } else { 88 | echo '

'; 89 | _e( 'Here you can replace the default sidebars. Simply select what sidebar you want to show for this post!', 'custom-sidebars' ); 90 | echo '

'; 91 | if ( ! empty( $sidebars ) ) { 92 | global $wp_registered_sidebars; 93 | $available = CustomSidebars::sort_sidebars_by_name( $wp_registered_sidebars ); 94 | foreach ( $sidebars as $s ) { ?> 95 | 96 |

97 | 100 | 110 |

111 | '; 115 | printf( 116 | __( 'All sidebars have been locked, you cannot replace them. Go to the widgets page to unlock a sidebar.', 'custom-sidebars' ), 117 | admin_url( 'widgets.php' ) 118 | ); 119 | echo '

'; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /customsidebars.php: -------------------------------------------------------------------------------- 1 | 910520, 118 | 'name' => 'Custom Sidebars Pro', 119 | 'screens' => array( 120 | 'widgets', 121 | ), 122 | ); 123 | /* end:pro */ 124 | 125 | foreach ( $modules as $path ) { 126 | if ( file_exists( $path ) ) { require_once $path; } 127 | } 128 | 129 | // Register the current plugin, for pro and free plugins! 130 | do_action( 131 | 'wdev-register-plugin', 132 | /* Plugin ID */ plugin_basename( __FILE__ ), 133 | /* Plugin Title */ 'CustomSidebars', 134 | /* https://wordpress.org */ '/plugins/custom-sidebars/', 135 | /* Email Button CTA */ $cta_label, 136 | /* getdrip Plugin param */ $drip_param 137 | ); 138 | 139 | // Initialize the plugin 140 | CustomSidebars::instance(); 141 | } 142 | 143 | inc_sidebars_init(); 144 | 145 | if ( ! class_exists( 'CustomSidebarsEmptyPlugin' ) ) { 146 | class CustomSidebarsEmptyPlugin extends WP_Widget { 147 | public function __construct() { 148 | parent::__construct( false, $name = 'CustomSidebarsEmptyPlugin' ); 149 | } 150 | public function form( $instance ) { 151 | //Nothing, just a dummy plugin to display nothing 152 | } 153 | public function update( $new_instance, $old_instance ) { 154 | //Nothing, just a dummy plugin to display nothing 155 | } 156 | public function widget( $args, $instance ) { 157 | echo ''; 158 | } 159 | } //end class 160 | } //end if class exists 161 | 162 | 163 | // Translation. 164 | function inc_sidebars_init_translation() { 165 | load_plugin_textdomain( 'custom-sidebars', false, basename( dirname( __FILE__ ) ) . '/languages' ); 166 | } 167 | add_action( 'plugins_loaded', 'inc_sidebars_init_translation' ); 168 | -------------------------------------------------------------------------------- /views/widgets.php: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 | 11 | 16 |
17 |

18 |
19 | 23 | 29 |
30 |
31 | 32 | 33 | 38 | 57 | 58 | 59 | 64 |
65 | 71 | 72 | 73 | | 74 | 80 | 81 | 82 | | 83 | 89 | 90 | 91 | | 92 |
93 | 94 | 95 | 100 |
101 | 118 |
119 | 120 | 121 | 126 |
127 | 128 |
129 | 130 | 131 | 136 |
137 | 138 |
139 | 140 | 141 | 146 |
147 | 148 |
149 | 150 | 155 |
156 | 157 |
158 | 159 |
160 | -------------------------------------------------------------------------------- /inc/class-custom-sidebars-checkup-notification.php: -------------------------------------------------------------------------------- 1 | singleton. 32 | * 33 | * @since 3.0.0 34 | */ 35 | private function __construct() { 36 | if ( ! is_admin() ) { 37 | return; 38 | } 39 | //add_action( 'admin_head', array( $this, 'init_admin_head' ) ); 40 | add_action( 'admin_head-widgets.php', array( $this, 'init_admin_head_in_widgets' ) ); 41 | add_action( 'wp_ajax_custom_sidebars_checkup_notification_dismiss', array( $this, 'dismiss' ) ); 42 | } 43 | 44 | /** 45 | * Save dismiss decision, no more show it. 46 | * 47 | * @since 3.0.0 48 | */ 49 | public function dismiss() { 50 | /** 51 | * Check: is nonce send? 52 | */ 53 | if ( ! isset( $_GET['_wpnonce'] ) ) { 54 | die; 55 | } 56 | /** 57 | * Check: is user id send? 58 | */ 59 | if ( ! isset( $_GET['user_id'] ) ) { 60 | die; 61 | } 62 | /** 63 | * Check: nonce 64 | */ 65 | $nonce_name = $this->nonce_name . $_GET['user_id']; 66 | if ( ! wp_verify_nonce( $_GET['_wpnonce'], $nonce_name ) ) { 67 | die; 68 | } 69 | /** 70 | * save result 71 | */ 72 | $result = add_user_meta( $_GET['user_id'], $this->dismiss_name, true, true ); 73 | if ( false == $result ) { 74 | update_user_meta( $_GET['user_id'], $this->dismiss_name, true ); 75 | } 76 | die; 77 | } 78 | 79 | /** 80 | * Admin header 81 | * 82 | * @since 3.0.0 83 | */ 84 | public function init_admin_head() { 85 | add_action( 'admin_notices', array( $this, 'admin_notice_scan' ) ); 86 | } 87 | 88 | /** 89 | * Admin notice scan! 90 | * 91 | * @since 3.0.1 92 | */ 93 | public function admin_notice_scan() { 94 | $user_id = get_current_user_id(); 95 | $state = get_user_meta( $user_id, $this->dismiss_name, true ); 96 | if ( $state ) { 97 | return; 98 | } 99 | lib3()->ui->add( CSB_CSS_URL . 'cs-scan.css' ); 100 | ?> 101 | 113 |
114 |

Warning: Some of your plugins may be slowing down your site. Run a free security and performance scan with WP Checkup.', 'custom-sidebars' ); ?>

115 |
116 | 117 | 118 | 119 | 120 | 121 | 122 |
123 | 126 |
127 | show_box( 'checkup' ); 147 | } 148 | 149 | /** 150 | * Show box. 151 | * 152 | * @since 3.0.4 153 | * 154 | * @param string $template_name Template name. 155 | */ 156 | private function show_box( $template_name ) { 157 | $method = sprintf( 'show_box_%s', $template_name ); 158 | if ( ! method_exists( $this, $method ) ) { 159 | return; 160 | } 161 | ?> 162 | 170 | 175 | 185 |
186 |
187 |

188 |

189 |
190 | 191 | 192 | 193 | 194 | 195 |
196 |
197 |
198 | 'custom_sidebar_uf_ad', 205 | 'utm_campaign' => 'custom_sidebar_plugin_uf_ad', 206 | 'utm_medium' => 'Custom Sidebars Plugin', 207 | ), 208 | 'https://premium.wpmudev.org/projects/category/themes/' 209 | ); 210 | ?> 211 |
212 |
213 |

214 |

215 |
216 |
217 | singleton. 64 | * 65 | * @since 2.0.9.1 66 | */ 67 | private function __construct() { 68 | $this->debug = false; 69 | $this->current_user_id = get_current_user_id(); 70 | if ( 0 == $this->current_user_id ) { 71 | $this->debug = apply_filters( 'custom_sidebars_explain', $this->debug ); 72 | } else { 73 | $this->debug = (boolean) get_user_meta( $this->current_user_id, 'custom_sidebars_explain', true ); 74 | $this->set_explain(); 75 | } 76 | add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ), 999 ); 77 | if ( false === $this->debug ) { 78 | return; 79 | } 80 | if ( is_admin() ) { 81 | return; 82 | } 83 | add_action( 'cs_explain', array( $this, 'add_info' ), 10, 2 ); 84 | add_action( 'wp_footer', array( $this, 'show_infos' ) ); 85 | add_action( 'dynamic_sidebar_before', array( $this, 'before_sidebar' ), 0, 2 ); 86 | add_action( 'dynamic_sidebar_after', array( $this, 'after_sidebar' ), 0, 2 ); 87 | add_action( 'wp_print_styles', array( $this, 'print_styles' ) ); 88 | } 89 | 90 | /** 91 | * Returns true if the "explain mode" is enabled. 92 | * Explain mode will display additional information in the front-end of the 93 | * website on why which sidebar/widget is displayed. 94 | * This is a per-user option (stored in current session) 95 | * 96 | * @since 2.0.9.1 97 | * @return boolean 98 | */ 99 | public function do_explain() { 100 | return $this->debug; 101 | } 102 | 103 | /** 104 | * Sets the explain state 105 | * 106 | * @since 2.0.9.1 107 | * @param string $state [on|off] 108 | */ 109 | public function set_explain() { 110 | if ( ! isset( $_GET['cs-explain'] ) ) { 111 | return; 112 | } 113 | if ( current_user_can( 'manage_options' ) && 'on' == $_GET['cs-explain'] ) { 114 | $this->debug = true; 115 | $result = add_user_meta( $this->current_user_id, 'custom_sidebars_explain', $this->debug, true ); 116 | if ( ! $result ) { 117 | update_user_meta( $this->current_user_id, 'custom_sidebars_explain', $this->debug ); 118 | } 119 | return; 120 | } 121 | $this->debug = false; 122 | delete_user_meta( $this->current_user_id, 'custom_sidebars_explain' ); 123 | } 124 | 125 | /** 126 | * Adds an info to the explanation output. 127 | * 128 | * @since 2.0.9.1 129 | */ 130 | public function add_info( $info, $new_item = false ) { 131 | if ( $new_item || 0 === count( $this->infos ) ) { 132 | $this->infos[] = $info; 133 | } else { 134 | $this->infos[ count( $this->infos ) - 1 ] .= '
' . $info; 135 | } 136 | } 137 | 138 | /** 139 | * Outputs the collected information to the webpage. 140 | * 141 | * @since 2.0.9.1 142 | */ 143 | public function show_infos() { 144 | ?> 145 |
146 | 152 |

Sidebar Infos

153 | 158 |
159 | ' . 187 | '
%1$s
' . 188 | @$wp_registered_sidebars[ $index ]['before_widget']; 189 | $wp_registered_sidebars[ $index ]['after_widget'] = 190 | @$wp_registered_sidebars[ $index ]['after_widget'] . 191 | '
' . 192 | ''; 193 | ?> 194 |
195 |
196 | 206 |
207 |
208 | 'cs-explain', 225 | 'title' => __( 'Sidebar Debug', 'custom-sidebars' ), 226 | 'href' => add_query_arg( 'cs-explain', 'on' ), 227 | 'parent' => 'top-secondary', 228 | 'meta' => array( 229 | 'title' => __( 'Turn on Custom Sidebars explain mode.', 'custom-sidebars' ), 230 | 'class' => 'debug-is-off', 231 | ), 232 | ); 233 | if ( $this->debug ) { 234 | $args['href'] = add_query_arg( 'cs-explain', 'off' ); 235 | $args['meta'] = array( 236 | 'title' => __( 'Turn off Custom Sidebars explain mode.', 'custom-sidebars' ), 237 | 'class' => 'cs-explain-on', 238 | ); 239 | } 240 | $wp_admin_bar->add_node( $args ); 241 | } 242 | 243 | /** 244 | * Print style for debug 245 | * 246 | * @since 3.0.8 247 | */ 248 | public function print_styles() { 249 | echo ''; 253 | } 254 | }; 255 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | *Similar structure as: Membership 2, Popup, Custom Sidebars, CoursePress* 4 | 5 | The **only** development branch for Custom Sidebars is `master`. This branch ultimately is responsible for creating the production branches that are finally published. 6 | 7 | Production branches are automatically built, based on the master branch. Any changes made to those other branches will be **overwritten**! 8 | 9 | **Remember:** `master` is the ONLY branch that should be edited and forked! 10 | 11 | **Notes:** 12 | 13 | 1. ONLY fork and submit pull-requests to the master branch `master`! 14 | 2. NEVER fork the production branches (below)! 15 | 3. NEVER publish/release the master branch `master` anywhere! 16 | 17 | ----- 18 | 19 | # PRODUCTION BRANCHES 20 | 21 | Production branches are always supposed to be stable and can be released/published at any time. 22 | 23 | 24 | ## Custom Sidebars Pro (customsidebars-pro) 25 | 26 | This is the official premium plugin that lives on WPMU DEV. 27 | 28 | It uses libraries that are not included in the free version (like WPMU DEV Notification integration) and has all features. 29 | 30 | 31 | ## Custom Sidebars (customsidebars-free) 32 | 33 | This is the free limited version that gets published to the WordPress plugin directory. 34 | 35 | It includes a special module to display up to 2 notifications to the user: Right after installation (sign up to a newsletter) and after seven days (rate plugin on wp.org) 36 | 37 | 38 | ----- 39 | 40 | # DEVELOPMENT 41 | 42 | As mentioned above: Only directly edit the branch `master`. Other branches should be only updated via grunt tasks (see section "Automation" below). 43 | 44 | Important: Do not let your IDE change the **source order** of the code. Fixing up formatting is fine, but moving code blocks around is not! It will confuse grunt and produce problems. 45 | 46 | ## Implement version differences 47 | 48 | As mentioned, we will only update the master branch with all changes, even if those changes only relate to one specific version (i.e. pro only changes). 49 | 50 | There is one way to add code that is specific to a single product only: 51 | 52 | 1. Wrap code in product conditions. 53 | 54 | ### Product conditions 55 | 56 | There are special comments in the `master` branch will make sure some code only end up on the pro plugin and some code only end up in the free plugin. 57 | 58 | Those are: 59 | 60 | ``` 61 | #!php 62 | /* start:pro */ 63 | echo 'This is only in customsidebars-pro'; 64 | /* end:pro */ 65 | 66 | /* start:free */ 67 | echo 'This is only in customsidebars-free'; 68 | /* end:free */ 69 | ``` 70 | 71 | 72 | ## Working with the branches 73 | 74 | ### Cloning 75 | 76 | Custom Sidebars uses submodules, so use the `--recursive` flag if you clone from command line: 77 | 78 | ``` 79 | #!bash 80 | $ git clone git@bitbucket.org:incsub/custom-sidebars-pro.git --recursive 81 | ``` 82 | 83 | If you already have a cloned repo, you will need to *init* the submodule. 84 | 85 | ``` 86 | #!bash 87 | $ git submodule init -- 88 | $ git submodule update 89 | ``` 90 | 91 | ### JS and CSS files 92 | 93 | Only edit/create javascript and css files inside the `/src` folders: 94 | 95 | * `js/src/*` for javascript. 96 | * `css/src/*` for css. Use .scss extension (SASS)! 97 | 98 | Important: Those folders are scanned and processed when running grunt. Files in base of `js/` and `css/` are **overwritten** by grunt. 99 | 100 | *Note:* 101 | There is a hardcoded list of js and scss files that are monitored and compiled by grunt. If you add a new js or scss file then you need to edit `Gruntfile.js` and add the new file to the file list in `js_files_concat` or `css_files_compile`. 102 | 103 | 104 | ----- 105 | 106 | # AUTOMATION 107 | 108 | See notes below on how to correctly set up and use grunt. 109 | 110 | Many tasks as well as basic quality control are done via grunt. Below is a list of supported tasks. 111 | 112 | **Important**: Before making a pull-request to the master branch always run the task `grunt` - this ensures that all .php, .js and .css files are validated. If an problems are reported then fix those problems before submitting the pull request. 113 | 114 | ### Grunt Task Runner 115 | 116 | **ALWAYS** use Grunt to build the production branches. Use the following commands: 117 | 118 | Category | Command | Action 119 | ---------| ------- | ------ 120 | Edit | `grunt watch` | Watch js and scss files, auto process them when changed. Similar as running `grunt` after each js/css change. 121 | Build | `grunt` | Run all default tasks: lint, compile js/css. **Run this task before submitting a pull-request**. 122 | Build | `grunt build` | Runs all default tasks + lang, builds pro + free product versions. 123 | Build | `grunt build:pro` | Same as build, but only build the pro plugin version. 124 | Build | `grunt build:free` | Same as build, but only build the free plugin version. 125 | 126 | 127 | ### Set up grunt 128 | 129 | #### 1. npm 130 | 131 | First install node.js from: 132 | 133 | ``` 134 | #!bash 135 | # Test it: 136 | $ npm -v 137 | 138 | # Install it system wide (optional but recommended): 139 | $ npm install -g npm 140 | ``` 141 | 142 | #### 2. grunt 143 | 144 | Install grunt by running this command in command line: 145 | 146 | ``` 147 | #!bash 148 | # Install grunt: 149 | $ npm install -g grunt-cli 150 | ``` 151 | 152 | #### 3. Setup project 153 | 154 | In command line switch to the `plugins/customsidebars` plugin folder. Run this command to set up grunt for the plugin: 155 | 156 | ``` 157 | #!bash 158 | # Install automation tools for the plugin: 159 | $ cd /wp-content/plugins/customsidebars 160 | $ npm install 161 | 162 | # Test it: 163 | $ grunt hello 164 | ``` 165 | 166 | #### 4. Install required tools 167 | 168 | Same as 3: Run commands in the `plugins/customsidebars` plugin folder: 169 | 170 | ``` 171 | #!bash 172 | $ cd /wp-content/plugins/customsidebars 173 | 174 | # Config git with your Name/Email 175 | $ git config user.email "" 176 | $ git config user.name "" 177 | ``` 178 | 179 | ---- 180 | 181 | # RELEASE 182 | 183 | ### 1. Build the release version 184 | 185 | 1.) Switch to `master` branch. 186 | 187 | 2.) Make sure the version number in **main plugin file** is correct and that the version in file `pacakge.json` matches the plugin version. (in package.json you have x.y.z format, so "1.2.3.4" becomes "1.2.34" here) 188 | 189 | 3.) Then run `grunt build` (or `grunt build:pro` / free). This will create a .zip archive of the release files and update the `customsidebars-pro`/`-free` branches. 190 | 191 | 4.) Only in `master` branch: There is a folder called `release/` which contains the release files as .zip archive. 192 | 193 | 5.a) **PRO**: Simply upload the zip file from the `release/` folder. The `customsidebars-pro` branch is not even needed. 194 | 195 | 5.b) **FREE**: (First set up a mixed repo as described below) After you built the free version, switch to the `customsidebars-free` branch and then commit those files to wp.org repository using SVN. 196 | 197 | 198 | ##### Setting up the mixed repo in same folder (SVN + GIT) 199 | 200 | For wp.org releases I found the easiest solution is to have a "mixed" working copy, that contains both .git and .svn files. This way we only have one place where code is stored. Bitbucket is our main version control. SVN is only used/updated when a new version of the free version should be published. 201 | 202 | This is the one-time setup routine I used to create this mixed working copy: 203 | 204 | 1. Get a working copy of the GIT repo in local folder `.../customsidebars` 205 | 2. Get a working copy of the SVN repo in local folder `.../customsidebars-svn` 206 | 3. Now copy all files/folders (also hidden ones) from `customsidebars-svn` into `customsidebars`. Important: Only add/overwrite files. Do not delete the .git folder/files!! 207 | 4. Verify in SVN that the customsidebars folder now is a valid SVN repo. Now you can delete the poup-svn folder again. 208 | 5. Now make sure that the .gitignore file contians the entry `.svn` 209 | 6. When .gitignore is correct then revert all files in git to restore the master-branch. This will cause a lot of edits show up in SVN, but ignore those. The only time you want to use SVN is after you switched to the `customsidebars-free` branch. ONLY THEN commit changes to SVN/wp.org!! 210 | 211 | ### 2. Update product versions 212 | 213 | The example shows how to update the Pro-version, but the process for free version is identical. 214 | 215 | 1. **Switch** to branch `master` 216 | 1. Run **grunt** command `$ grunt build:pro` 217 | 1. **Switch** to branch `customsidebars-pro` 218 | 1. Do a git **pull**, *possibly some conflicts are identified!* 219 | 1. Do NOT resolve the conflicts, but **revert** the conflicting files to last version!! 220 | > Grunt already committed the correct file version to git. The conflicts are irrelevant! 221 | 1. Now **commit** and **push** the changes to bitbucket 222 | -------------------------------------------------------------------------------- /views/widgets-location.php: -------------------------------------------------------------------------------- 1 | ". 18 | * @param string $class Optinal classname added to the wrapper element. 19 | */ 20 | if ( ! function_exists( '_show_replaceable' ) ) { 21 | function _show_replaceable( $sidebar, $prefix, $cat_name, $class = '' ) { 22 | $base_id = 'cs-' . $prefix; 23 | $inp_id = $base_id . '-' . $sidebar['id']; 24 | $inp_name = '___cs___' . $prefix . '___' . $sidebar['id']; 25 | $sb_id = $sidebar['id']; 26 | $class = (empty( $class ) ? '' : ' ' . $class); 27 | ?> 28 |
32 | 43 |
44 | 57 |
58 |
59 | 63 |
64 | 65 | 66 | 67 |
68 |

69 | ... 70 |

71 |
72 |

73 | 74 | Post or Page & set it ' . 79 | 'up via the sidebars metabox.', 'custom-sidebars' 80 | ), 81 | admin_url( 'edit.php' ), 82 | admin_url( 'edit.php?post_type=page' ) 83 | ); 84 | ?> 85 |

86 | 87 | 90 | 96 |
97 |

98 |
99 | 100 |

101 |
102 |

103 | 104 |

105 | $details ) { 110 | $cat_name = __( 'categories', 'custom-sidebars' ); 111 | _show_replaceable( $details, 'cat', $cat_name ); 112 | } 113 | ?> 114 |
115 | 116 |
117 | $details ) { 122 | $cat_name = __( 'Post Types', 'custom-sidebars' ); 123 | _show_replaceable( $details, 'pt', $cat_name ); 124 | } 125 | ?> 126 |
127 | $taxonomy ) { 133 | echo '
'; 134 | foreach ( $sidebars as $sb_id => $details ) { 135 | _show_replaceable( $details, $taxonomy_slug, $taxonomy->label ); 136 | } 137 | echo '
'; 138 | } 139 | ?> 140 |
141 |
142 | 148 |
149 |

150 |
151 | 152 |

153 |
154 |

155 |

156 | 157 | 158 | 159 |

160 |
161 |
162 | $details ) { 167 | $cat_name = __( 'Archive Types', 'custom-sidebars' ); 168 | _show_replaceable( $details, 'arc', $cat_name ); 169 | } 170 | ?> 171 |
172 |
173 | $details ) { 178 | $cat_name = __( 'Category Archives', 'custom-sidebars' ); 179 | _show_replaceable( $details, 'arc-cat', $cat_name ); 180 | } 181 | ?> 182 |
183 |
184 | $details ) { 189 | $cat_name = __( 'Author Archives', 'custom-sidebars' ); 190 | _show_replaceable( $details, 'arc-aut', $cat_name ); 191 | } 192 | ?> 193 |
194 |
195 |
196 |
197 | 198 | 204 |
205 |

206 |
207 | 208 |

209 |
210 |

211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 |

226 | 227 |
228 |
229 | 230 | 238 |
239 |

240 |
241 | 242 |

243 |
244 |

245 | 246 |

247 | $one ) { 250 | printf( 251 | '%s', 252 | esc_attr( $id ), 253 | esc_attr( implode( ' ', $classes ) ), 254 | esc_html( $one['title'] ) 255 | ); 256 | $classes = array( 'tab' ); 257 | } 258 | ?> 259 |

260 |
261 | $one ) { 264 | printf( 265 | '
', 266 | esc_attr( $id ), 267 | esc_attr( implode( ' ', $classes ) ) 268 | ); 269 | foreach ( $sidebars as $sb_id => $details ) { 270 | _show_replaceable( $details, $id, $one['cat_name'] ); 271 | } 272 | echo '
'; 273 | $classes = array( 'tab' ); 274 | } 275 | ?> 276 |
277 |
278 |
279 | 282 | 283 |
284 | 285 | 286 |
287 | 288 |
289 | -------------------------------------------------------------------------------- /inc/class-custom-sidebars-cloning.php: -------------------------------------------------------------------------------- 1 | singleton. 41 | * 42 | * @since 2.0 43 | */ 44 | private function __construct() { 45 | if ( is_admin() ) { 46 | // in_widget_form: Add our button inside each widget. 47 | add_action( 48 | 'in_widget_form', 49 | array( $this, 'admin_widget_button' ), 50 | 10, 3 51 | ); 52 | 53 | // in_widget_form: Update data of widget-group (see notes below). 54 | add_action( 55 | 'in_widget_form', 56 | array( $this, 'update_widget_group' ), 57 | 10, 3 58 | ); 59 | 60 | // When the widget is saved (via Ajax) we save our options. 61 | add_filter( 62 | 'widget_update_callback', 63 | array( $this, 'admin_widget_update' ), 64 | 9999, 4 65 | ); 66 | 67 | // Load the javascript support file for this module. 68 | $javascript_file = 'cs-cloning.min.js'; 69 | if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { 70 | $javascript_file = 'cs-cloning.js'; 71 | } 72 | lib3()->ui->add( CSB_JS_URL . $javascript_file, 'widgets.php' ); 73 | lib3()->ui->add( CSB_CSS_URL . 'cs-cloning.css', 'widgets.php' ); 74 | } 75 | } 76 | 77 | /** 78 | * Extracts and sanitizes the CSB cloning data from the widget instance. 79 | * Cloning data contains the parent widget. 80 | * 81 | * @since 2.0 82 | * @param array $instance The widget instance data. 83 | * @return array Sanitized CSB cloning data. 84 | */ 85 | protected function get_widget_data( $instance ) { 86 | $data = array(); 87 | 88 | if ( isset( $instance['csb_clone'] ) ) { 89 | $data = $instance['csb_clone']; 90 | } 91 | 92 | if ( ! is_array( $data ) ) { 93 | $data = array(); 94 | } 95 | 96 | // group: ID of the group 97 | 98 | if ( isset( $data['group'] ) && is_numeric( $data['group'] ) && $data['group'] > 0 ) { 99 | $group = preg_replace( '/^.*-(\d+)$/', '$1', $data['group'] ); 100 | $state = @$data['state']; 101 | } else { 102 | $group = $this->new_group_id(); 103 | $state = 'new'; 104 | $data['group'] = intval( $group ); 105 | } 106 | 107 | // state: ok|empty|new 108 | if ( ! in_array( $state, array( 'ok', 'empty', 'new' ) ) ) { 109 | $state = 'new'; 110 | } 111 | $data['state'] = $state; 112 | 113 | return $data; 114 | } 115 | 116 | /** 117 | * Returns a new/unique group-ID. 118 | * 119 | * @since 2.0 120 | */ 121 | protected function new_group_id() { 122 | global $wp_registered_widgets; 123 | static $Used_ids = null; 124 | $group_id = 1; 125 | 126 | if ( null === $Used_ids ) { 127 | $Used_ids = array(); 128 | 129 | // Loop though all widgets to fetch used IDs. 130 | foreach ( $wp_registered_widgets as $id => $data ) { 131 | if ( ! isset( $data['callback'] ) ) { continue; } 132 | if ( ! is_array( $data['callback'] ) ) { continue; } 133 | 134 | $widget = reset( $data['callback'] ); 135 | $settings = false; 136 | if ( is_object( $widget ) && method_exists( $widget, 'get_settings' ) ) { 137 | $settings = $widget->get_settings(); 138 | } 139 | 140 | // Check the database settings of the widget to find group IDs. 141 | if ( is_array( $settings ) ) { 142 | foreach ( $settings as $instance ) { 143 | if ( ! isset( $instance['csb_clone'] ) ) { continue; } 144 | if ( ! empty( $instance['csb_clone']['group'] ) ) { 145 | $group = $instance['csb_clone']['group']; 146 | if ( ! in_array( $group, $Used_ids ) ) { 147 | $Used_ids[] = $group; 148 | } 149 | } // endif: empty(group) 150 | } // endforeach 151 | } // endif: is_array() 152 | } // endforeach 153 | 154 | } 155 | 156 | // Find the first free group-ID. 157 | while ( in_array( $group_id, $Used_ids ) ) { 158 | $group_id += 1; 159 | } 160 | $Used_ids[] = $group_id; 161 | 162 | return $group_id; 163 | } 164 | 165 | /** 166 | * Finds the settings for the specified group inside the settings array. 167 | * 168 | * @since 2.0 169 | */ 170 | protected function settings_for_group( $settings, $group ) { 171 | if ( is_numeric( $group ) && $group > 0 ) { 172 | foreach ( $settings as $data ) { 173 | $item_group = @$data['csb_clone']['group']; 174 | $item_status = @$data['csb_clone']['state']; 175 | 176 | if ( $group == $item_group && 'ok' == $item_status ) { 177 | return $data; 178 | } 179 | } 180 | } 181 | function_exists( 'wp_debug' ) && wp_debug( 'class-custom-sidebars-cloning.php:162', 'FAILED' ); 182 | return false; 183 | } 184 | 185 | /** 186 | * Action handler for 'in_widget_form' 187 | * 188 | * @since 2.0 189 | */ 190 | public function admin_widget_button( $widget, $return, $instance ) { 191 | $data = $this->get_widget_data( $instance ); 192 | $is_linked = (0 != $data['group']); 193 | 194 | ?> 195 |
196 | 202 | 203 | 204 | 205 | id ) ) : ?> 206 | 207 | 208 | 209 | 210 | 211 |
212 | group_data. {@see update_linked_widgets} 227 | * 228 | * After the widget_update_callback filter is called the widget is rendered 229 | * again. Now the in_widget_form hook is called. It is not related to saving 230 | * the widget but provides a way to update the settings in chronolically 231 | * correct order, this is why we hijack it for saving settings... 232 | * 233 | * @since 2.0 234 | */ 235 | public function update_widget_group( $widget, $return, $instance ) { 236 | if ( ! empty( $this->group_data ) ) { 237 | $widget->save_settings( $this->group_data ); 238 | } 239 | } 240 | 241 | /** 242 | * Apply cloning logic when user saves the widget. 243 | * 244 | * @since 2.0 245 | * @param array $new_instance New settings for this instance as input by the user. 246 | * @param array $old_instance Old settings for this instance. 247 | * @param WP_Widget $widget The current widget instance. 248 | * @return array Modified settings. 249 | */ 250 | public function admin_widget_update( $instance, $new_instance, $old_instance, $widget ) { 251 | $data = $this->get_widget_data( $_POST ); 252 | 253 | $instance['csb_clone'] = $data; 254 | $settings = $widget->get_settings(); 255 | $my_id = $widget->number; 256 | 257 | switch ( @$instance['csb_clone']['state'] ) { 258 | case 'empty': 259 | return $this->populate_widget( $my_id, $settings, $instance, $widget ); 260 | break; 261 | 262 | case 'ok': 263 | return $this->update_linked_widgets( $my_id, $settings, $instance, $widget ); 264 | break; 265 | 266 | default: 267 | $instance['csb_clone']['state'] = 'ok'; 268 | return $instance; 269 | } 270 | } 271 | 272 | /** 273 | * This function returns the $instance data of a new clone. The data is 274 | * populated with the values of the widget-group. 275 | */ 276 | protected function populate_widget( $id, $settings, $instance, $widget ) { 277 | $instance['csb_clone']['state'] = 'ok'; 278 | 279 | if ( ! isset( $instance['csb_clone']['group'] ) ) { 280 | // Widget does not have any cloning information. 281 | return $instance; 282 | } 283 | 284 | $group = $instance['csb_clone']['group']; 285 | if ( empty( $group ) ) { 286 | // Widget does not have a group (anymore). 287 | return $instance; 288 | } 289 | 290 | $group_data = $this->settings_for_group( $settings, $group ); 291 | if ( empty( $group_data ) ) { 292 | // The specified group does not exist (anymore). 293 | return $instance; 294 | } 295 | 296 | // Success, fetch the config from group! 297 | $instance = $group_data; 298 | return $instance; 299 | } 300 | 301 | /** 302 | * Update ALL widgets in the same group as the specified widget. 303 | */ 304 | protected function update_linked_widgets( $id, $settings, $instance, $widget ) { 305 | $instance['csb_clone']['state'] = 'ok'; 306 | $group_data = $instance; 307 | $my_group = @$group_data['csb_clone']['group']; 308 | 309 | foreach ( $settings as $key => $the_inst ) { 310 | if ( ! isset( $the_inst['csb_clone']['group'] ) ) { 311 | // Widget does not have any cloning information. 312 | continue; 313 | } 314 | 315 | $group = $the_inst['csb_clone']['group']; 316 | if ( empty( $group ) ) { 317 | // Widget does not have a group (anymore). 318 | continue; 319 | } 320 | 321 | if ( $group != $my_group ) { 322 | // This widget does not belong to the current group. 323 | continue; 324 | } 325 | 326 | // Success, this widget needs to be updated! 327 | $settings[ $key ] = $group_data; 328 | } 329 | 330 | $settings[ $id ] = $group_data; 331 | $this->group_data = $settings; 332 | 333 | return $instance; 334 | } 335 | }; 336 | -------------------------------------------------------------------------------- /assets/js/src/cs-cloning.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Javascript support for the cloning module. 3 | */ 4 | /*global jQuery:false */ 5 | /*global window:false */ 6 | /*global document:false */ 7 | /*global wp:false */ 8 | /*global wpmUi:false */ 9 | 10 | jQuery(function init_cloning() { 11 | var $doc = jQuery( document ), 12 | $all = jQuery( '#widgets-right' ), 13 | is_cloning = false; 14 | 15 | /** 16 | * Updates all group_id values for the widget-templates to the next free id. 17 | */ 18 | var update_template_groups = function update_template_groups() { 19 | var $groups = jQuery( '#widgets-left input.csb-clone-group' ), 20 | next_id = parseInt( $groups.first().val() ); 21 | while ( $all.find( 'input.csb-clone-group[value="' + next_id + '"]' ).length ) { 22 | next_id += 1; 23 | } 24 | $groups.val( next_id ); 25 | }; 26 | 27 | /** 28 | * Clones the widget: 29 | * Add a new widget using default WordPress JS API and then update all the 30 | * input values of the new widget to match the original widget. 31 | */ 32 | var clone_widget = function clone_widget( ev ) { 33 | var $widget = jQuery( this ).closest( '.widget' ), 34 | $available = jQuery( '#widgets-left' ), 35 | $chooser = jQuery( '.widgets-chooser' ), 36 | $content = jQuery( '#wpbody-content' ); 37 | 38 | ev.preventDefault(); 39 | is_cloning = true; 40 | 41 | // 1. If the current widget is new then first save the current widget 42 | var state = $widget.find( 'input.csb-clone-state' ).val(); 43 | if ( 'new' === state ) { 44 | window.wpWidgets.save( $widget, 0, 0, 0 ); 45 | } 46 | 47 | // 2. Close any open chooser 48 | window.wpWidgets.clearWidgetSelection(); 49 | $chooser.slideUp( 200, function() { 50 | $chooser.hide(); 51 | $content.append( this ); 52 | }); 53 | 54 | // 3. Find the "widget-in-question". 55 | var class_name = $widget.find('input.id_base').val(), 56 | $base = $available.find('input.id_base[value="' + class_name + '"]'), 57 | $in_question = $base.closest( '.widget' ); 58 | $in_question.addClass( 'widget-in-question' ); 59 | 60 | // 4. Provide data about the origin widget. 61 | var group_id = $widget.find( 'input.csb-clone-group' ).val(), 62 | $contr = $in_question.find( '.widget-control-actions' ), 63 | $group = $in_question.find( 'input.csb-clone-group' ), 64 | $state = $in_question.find( 'input.csb-clone-state' ); 65 | $group.val( group_id ); 66 | $state.val( 'empty' ); 67 | 68 | // 5. Select the current sidebar in the chooser. 69 | var $sidebar = $widget.closest( '.widgets-sortables' ), 70 | sb_id = $sidebar.attr( 'id' ); 71 | $chooser.find ( '.widgets-chooser-selected' ).removeClass( 'widgets-chooser-selected' ); 72 | $chooser.find( 'li' ).each( function() { 73 | var $li = jQuery( this ); 74 | if ( sb_id === $li.data('sidebarId') ) { 75 | $li.addClass( 'widgets-chooser-selected' ).focus(); 76 | } 77 | }); 78 | 79 | // 6. Add the new widget to the sidebar. 80 | // This will directly trigger the ajax command to save the widget. 81 | window.wpWidgets.addWidget( $chooser ); 82 | 83 | // 7. Remove the custom elements and information again. 84 | window.wpWidgets.clearWidgetSelection(); 85 | update_template_groups(); 86 | 87 | is_cloning = false; 88 | 89 | return false; 90 | }; 91 | 92 | /** 93 | * Update all widgets belonging to the same group. 94 | */ 95 | var prepare_update_group = function prepare_update_group( ev ) { 96 | var $widget = jQuery( this ).closest( '.widget' ), 97 | group_id = $widget.find( 'input.csb-clone-group' ).val(), 98 | $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ).not( $widget ); 99 | $members.each(function() { 100 | var $item = jQuery( this ), 101 | $state = $item.find( 'input.csb-clone-state' ); 102 | $item.addClass('wpmui-loading').attr( 'data-reload', true ); 103 | }); 104 | }; 105 | 106 | /** 107 | * Moves the "Clone" button next to the save button. 108 | */ 109 | var init_widget = function init_widget( ev, el ) { 110 | var $widget = jQuery( el ).closest( '.widget' ), 111 | $btn = $widget.find( '.csb-clone-button' ), 112 | $target = $widget.find( '.widget-control-actions .widget-control-save' ), 113 | $spinner = $widget.find( '.widget-control-actions .spinner' ), 114 | $btn_save = $widget.find( '.widget-control-save' ); 115 | 116 | if ( $widget.data( '_csb_cloning' ) ) { 117 | return; 118 | } 119 | 120 | $spinner.insertBefore( $target ).css({ 'float': 'left' }); 121 | $btn.insertBefore( $target ).click( clone_widget ); 122 | $btn_save.click( prepare_update_group ); 123 | 124 | $widget.data( '_csb_cloning', true ); 125 | }; 126 | 127 | /** 128 | * Updates the group-counter when a widget is added. 129 | */ 130 | var update_group_counter = function update_group_counter( ev, el ) { 131 | // We do NOT want to change the group-id when we clone a widget... 132 | if ( is_cloning ) { 133 | return false; 134 | } 135 | var $widget = jQuery( el ).closest( '.widget' ), 136 | $widget_group = $widget.find( 'input.csb-clone-group' ), 137 | group_id = parseInt( $widget_group.val() ), 138 | check = null; 139 | do { 140 | check = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ); 141 | if ( ! check.length || ( 1 === check.length && check[0] === $widget_group[0] ) ) { 142 | break; 143 | } else { 144 | group_id += 1; 145 | } 146 | } 147 | while ( true ); 148 | 149 | $widget_group.val( group_id ); 150 | update_template_groups(); 151 | }; 152 | 153 | 154 | /** 155 | * Viually highlights all widgets of the same group. 156 | */ 157 | var mark_group = function mark_group( ev ) { 158 | var $widget = jQuery( this ).closest( '.widget' ), 159 | group_id = $widget.find( 'input.csb-clone-group' ).val(), 160 | $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ); 161 | 162 | if ( isNaN( group_id ) || group_id < 1 ) { 163 | return; 164 | } 165 | 166 | $members.addClass('csb-marker'); 167 | $widget.removeClass('csb-marker'); 168 | }; 169 | 170 | /** 171 | * Removes the visual highlighting of group widgets. 172 | */ 173 | var unmark_group = function unmark_group( ev ) { 174 | var $marked = jQuery( '.widget.csb-marker' ); 175 | $marked.removeClass('csb-marker'); 176 | }; 177 | 178 | /** 179 | * Remove widget from group/assign to group again (only works until widget 180 | * was saved.) 181 | */ 182 | var toggle_group = function toggle_group( ev ) { 183 | var $widget = jQuery( this ).closest( '.widget' ), 184 | $title = $widget.find( '.widget-title h4' ), 185 | $icon = $title.find( '.btn-clone-group' ), 186 | $group = $widget.find( 'input.csb-clone-group' ); 187 | ev.preventDefault(); 188 | ev.stopPropagation(); 189 | if ( $title.hasClass( 'group-active' ) ) { 190 | $title.removeClass( 'group-active' ); 191 | $icon.removeClass('dashicons-admin-links').addClass('dashicons-editor-unlink'); 192 | $group.data( 'group', $group.val() ); 193 | $group.val( 0 ); 194 | unmark_group(); 195 | } else { 196 | $title.addClass( 'group-active' ); 197 | $icon.addClass('dashicons-admin-links').removeClass('dashicons-editor-unlink'); 198 | $group.val( $group.data( 'group' ) ); 199 | mark_group.call( this, [ev] ); 200 | } 201 | return false; 202 | }; 203 | 204 | /** 205 | * Adds icons to all widgets that are inside a group. 206 | */ 207 | var init_group_icons = function init_group_icons() { 208 | var $groups = $all.find( 'input.csb-clone-group' ); 209 | $groups.each(function() { 210 | var group_id = jQuery( this ).val(), 211 | $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ), 212 | $titles = $members.find( '.widget-title h4, .widget-title h3' ), 213 | action = 'add'; 214 | if ( isNaN( group_id ) || group_id < 1 ) { 215 | action = 'remove'; 216 | } 217 | if ( $members.length < 2 ) { 218 | action = 'remove'; 219 | } 220 | // Always remove the icons from the group. 221 | $titles.removeClass( 'csb-group group-active' ) 222 | .find( '.btn-clone-group' ).remove(); 223 | $members.removeAttr( 'data-csb-icon' ); 224 | // If action is "add" then we add the icons again. 225 | if ( action === 'add' ) { 226 | $titles.addClass( 'csb-group group-active' ) 227 | .prepend( ' ' ); 228 | $titles.find( '.btn-clone-group' ) 229 | .hover( mark_group, unmark_group ) 230 | .click( toggle_group ); 231 | } 232 | }); 233 | }; 234 | 235 | /** 236 | * Saves the specified widget if the clone-state is "empty". 237 | */ 238 | var populate_widget = function populate_widget( $widget ) { 239 | var $state = $widget.find( 'input.csb-clone-state' ); 240 | 241 | if ( $state.val() === 'empty' ) { 242 | $widget.addClass( 'wpmui-loading' ); 243 | window.wpWidgets.save( $widget, 0, 1, 0 ); 244 | } 245 | }; 246 | 247 | /** 248 | * Update all widgets belonging to the same group. 249 | */ 250 | var update_group_widgets = function update_group_widgets( el ) { 251 | var $widgets = $all.find( '.widget[data-reload]' ); 252 | 253 | $widgets.each(function() { 254 | var $item = jQuery( this ), 255 | $state = $item.find( 'input.csb-clone-state' ); 256 | 257 | $state.val( 'empty' ); 258 | $item.removeAttr( 'data-reload' ); 259 | window.wpWidgets.save( $item, 0, 0, 0 ); 260 | }); 261 | }; 262 | 263 | /** 264 | * Global ajax observer reacts to all ajax responses. We need this to find 265 | * out when a new widget is saved for the first time. 266 | */ 267 | var ajax_observer = function ajax_observer( ev, xhr, opt, resp ) { 268 | var data = ( 'string' === typeof opt.data ? opt.data : '' ), 269 | find_action = data.match( /^.*&action=([^&]+).*$/ ), 270 | find_widget = data.match( /^.*&widget-id=([^&]+).*$/ ), 271 | action = (find_action && find_action.length === 2 ? find_action[1] : ''), 272 | widget = (find_widget && find_widget.length === 2 ? find_widget[1] : ''); 273 | 274 | if ( ! widget.length ) { 275 | return; 276 | } 277 | 278 | var $base = jQuery( '.widget input.widget-id[value="' + widget + '"]' ), 279 | $widget = $base.closest( '.widget' ); 280 | 281 | switch ( action ) { 282 | case 'save-widget': 283 | $widget.removeClass( 'wpmui-loading' ); 284 | if ( ! resp.length ) { 285 | // Populate widget with data from group, if required. 286 | populate_widget( $widget ); 287 | } else if ( resp.match( /^deleted:/ ) ) { 288 | // Widget was deleted and is removed with animation. 289 | window.setTimeout( init_group_icons, 400 ); 290 | } else { 291 | // Existing widget was updated. 292 | init_group_icons(); 293 | update_group_widgets( $widget ); 294 | } 295 | break; 296 | 297 | default: 298 | // Unrelated ajax event. 299 | } 300 | }; 301 | 302 | 303 | $all.find( '.widget' ).each( init_widget ); 304 | $doc.on( 'widget-added', init_widget ); 305 | $doc.on( 'widget-added', update_group_counter ); 306 | $doc.ajaxSuccess( ajax_observer ); 307 | 308 | init_group_icons(); 309 | update_template_groups(); 310 | }); 311 | -------------------------------------------------------------------------------- /assets/js/cs-cloning.js: -------------------------------------------------------------------------------- 1 | /*! Custom Sidebars - v3.2.3 2 | * https://premium.wpmudev.org/project/custom-sidebars-pro/ 3 | * Copyright (c) 2019; * Licensed GPLv2+ */ 4 | /*global jQuery:false */ 5 | /*global window:false */ 6 | /*global document:false */ 7 | /*global wp:false */ 8 | /*global wpmUi:false */ 9 | 10 | jQuery(function init_cloning() { 11 | var $doc = jQuery( document ), 12 | $all = jQuery( '#widgets-right' ), 13 | is_cloning = false; 14 | 15 | /** 16 | * Updates all group_id values for the widget-templates to the next free id. 17 | */ 18 | var update_template_groups = function update_template_groups() { 19 | var $groups = jQuery( '#widgets-left input.csb-clone-group' ), 20 | next_id = parseInt( $groups.first().val() ); 21 | while ( $all.find( 'input.csb-clone-group[value="' + next_id + '"]' ).length ) { 22 | next_id += 1; 23 | } 24 | $groups.val( next_id ); 25 | }; 26 | 27 | /** 28 | * Clones the widget: 29 | * Add a new widget using default WordPress JS API and then update all the 30 | * input values of the new widget to match the original widget. 31 | */ 32 | var clone_widget = function clone_widget( ev ) { 33 | var $widget = jQuery( this ).closest( '.widget' ), 34 | $available = jQuery( '#widgets-left' ), 35 | $chooser = jQuery( '.widgets-chooser' ), 36 | $content = jQuery( '#wpbody-content' ); 37 | 38 | ev.preventDefault(); 39 | is_cloning = true; 40 | 41 | // 1. If the current widget is new then first save the current widget 42 | var state = $widget.find( 'input.csb-clone-state' ).val(); 43 | if ( 'new' === state ) { 44 | window.wpWidgets.save( $widget, 0, 0, 0 ); 45 | } 46 | 47 | // 2. Close any open chooser 48 | window.wpWidgets.clearWidgetSelection(); 49 | $chooser.slideUp( 200, function() { 50 | $chooser.hide(); 51 | $content.append( this ); 52 | }); 53 | 54 | // 3. Find the "widget-in-question". 55 | var class_name = $widget.find('input.id_base').val(), 56 | $base = $available.find('input.id_base[value="' + class_name + '"]'), 57 | $in_question = $base.closest( '.widget' ); 58 | $in_question.addClass( 'widget-in-question' ); 59 | 60 | // 4. Provide data about the origin widget. 61 | var group_id = $widget.find( 'input.csb-clone-group' ).val(), 62 | $contr = $in_question.find( '.widget-control-actions' ), 63 | $group = $in_question.find( 'input.csb-clone-group' ), 64 | $state = $in_question.find( 'input.csb-clone-state' ); 65 | $group.val( group_id ); 66 | $state.val( 'empty' ); 67 | 68 | // 5. Select the current sidebar in the chooser. 69 | var $sidebar = $widget.closest( '.widgets-sortables' ), 70 | sb_id = $sidebar.attr( 'id' ); 71 | $chooser.find ( '.widgets-chooser-selected' ).removeClass( 'widgets-chooser-selected' ); 72 | $chooser.find( 'li' ).each( function() { 73 | var $li = jQuery( this ); 74 | if ( sb_id === $li.data('sidebarId') ) { 75 | $li.addClass( 'widgets-chooser-selected' ).focus(); 76 | } 77 | }); 78 | 79 | // 6. Add the new widget to the sidebar. 80 | // This will directly trigger the ajax command to save the widget. 81 | window.wpWidgets.addWidget( $chooser ); 82 | 83 | // 7. Remove the custom elements and information again. 84 | window.wpWidgets.clearWidgetSelection(); 85 | update_template_groups(); 86 | 87 | is_cloning = false; 88 | 89 | return false; 90 | }; 91 | 92 | /** 93 | * Update all widgets belonging to the same group. 94 | */ 95 | var prepare_update_group = function prepare_update_group( ev ) { 96 | var $widget = jQuery( this ).closest( '.widget' ), 97 | group_id = $widget.find( 'input.csb-clone-group' ).val(), 98 | $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ).not( $widget ); 99 | $members.each(function() { 100 | var $item = jQuery( this ), 101 | $state = $item.find( 'input.csb-clone-state' ); 102 | $item.addClass('wpmui-loading').attr( 'data-reload', true ); 103 | }); 104 | }; 105 | 106 | /** 107 | * Moves the "Clone" button next to the save button. 108 | */ 109 | var init_widget = function init_widget( ev, el ) { 110 | var $widget = jQuery( el ).closest( '.widget' ), 111 | $btn = $widget.find( '.csb-clone-button' ), 112 | $target = $widget.find( '.widget-control-actions .widget-control-save' ), 113 | $spinner = $widget.find( '.widget-control-actions .spinner' ), 114 | $btn_save = $widget.find( '.widget-control-save' ); 115 | 116 | if ( $widget.data( '_csb_cloning' ) ) { 117 | return; 118 | } 119 | 120 | $spinner.insertBefore( $target ).css({ 'float': 'left' }); 121 | $btn.insertBefore( $target ).click( clone_widget ); 122 | $btn_save.click( prepare_update_group ); 123 | 124 | $widget.data( '_csb_cloning', true ); 125 | }; 126 | 127 | /** 128 | * Updates the group-counter when a widget is added. 129 | */ 130 | var update_group_counter = function update_group_counter( ev, el ) { 131 | // We do NOT want to change the group-id when we clone a widget... 132 | if ( is_cloning ) { 133 | return false; 134 | } 135 | var $widget = jQuery( el ).closest( '.widget' ), 136 | $widget_group = $widget.find( 'input.csb-clone-group' ), 137 | group_id = parseInt( $widget_group.val() ), 138 | check = null; 139 | do { 140 | check = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ); 141 | if ( ! check.length || ( 1 === check.length && check[0] === $widget_group[0] ) ) { 142 | break; 143 | } else { 144 | group_id += 1; 145 | } 146 | } 147 | while ( true ); 148 | 149 | $widget_group.val( group_id ); 150 | update_template_groups(); 151 | }; 152 | 153 | 154 | /** 155 | * Viually highlights all widgets of the same group. 156 | */ 157 | var mark_group = function mark_group( ev ) { 158 | var $widget = jQuery( this ).closest( '.widget' ), 159 | group_id = $widget.find( 'input.csb-clone-group' ).val(), 160 | $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ); 161 | 162 | if ( isNaN( group_id ) || group_id < 1 ) { 163 | return; 164 | } 165 | 166 | $members.addClass('csb-marker'); 167 | $widget.removeClass('csb-marker'); 168 | }; 169 | 170 | /** 171 | * Removes the visual highlighting of group widgets. 172 | */ 173 | var unmark_group = function unmark_group( ev ) { 174 | var $marked = jQuery( '.widget.csb-marker' ); 175 | $marked.removeClass('csb-marker'); 176 | }; 177 | 178 | /** 179 | * Remove widget from group/assign to group again (only works until widget 180 | * was saved.) 181 | */ 182 | var toggle_group = function toggle_group( ev ) { 183 | var $widget = jQuery( this ).closest( '.widget' ), 184 | $title = $widget.find( '.widget-title h4' ), 185 | $icon = $title.find( '.btn-clone-group' ), 186 | $group = $widget.find( 'input.csb-clone-group' ); 187 | ev.preventDefault(); 188 | ev.stopPropagation(); 189 | if ( $title.hasClass( 'group-active' ) ) { 190 | $title.removeClass( 'group-active' ); 191 | $icon.removeClass('dashicons-admin-links').addClass('dashicons-editor-unlink'); 192 | $group.data( 'group', $group.val() ); 193 | $group.val( 0 ); 194 | unmark_group(); 195 | } else { 196 | $title.addClass( 'group-active' ); 197 | $icon.addClass('dashicons-admin-links').removeClass('dashicons-editor-unlink'); 198 | $group.val( $group.data( 'group' ) ); 199 | mark_group.call( this, [ev] ); 200 | } 201 | return false; 202 | }; 203 | 204 | /** 205 | * Adds icons to all widgets that are inside a group. 206 | */ 207 | var init_group_icons = function init_group_icons() { 208 | var $groups = $all.find( 'input.csb-clone-group' ); 209 | $groups.each(function() { 210 | var group_id = jQuery( this ).val(), 211 | $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ), 212 | $titles = $members.find( '.widget-title h4, .widget-title h3' ), 213 | action = 'add'; 214 | if ( isNaN( group_id ) || group_id < 1 ) { 215 | action = 'remove'; 216 | } 217 | if ( $members.length < 2 ) { 218 | action = 'remove'; 219 | } 220 | // Always remove the icons from the group. 221 | $titles.removeClass( 'csb-group group-active' ) 222 | .find( '.btn-clone-group' ).remove(); 223 | $members.removeAttr( 'data-csb-icon' ); 224 | // If action is "add" then we add the icons again. 225 | if ( action === 'add' ) { 226 | $titles.addClass( 'csb-group group-active' ) 227 | .prepend( ' ' ); 228 | $titles.find( '.btn-clone-group' ) 229 | .hover( mark_group, unmark_group ) 230 | .click( toggle_group ); 231 | } 232 | }); 233 | }; 234 | 235 | /** 236 | * Saves the specified widget if the clone-state is "empty". 237 | */ 238 | var populate_widget = function populate_widget( $widget ) { 239 | var $state = $widget.find( 'input.csb-clone-state' ); 240 | 241 | if ( $state.val() === 'empty' ) { 242 | $widget.addClass( 'wpmui-loading' ); 243 | window.wpWidgets.save( $widget, 0, 1, 0 ); 244 | } 245 | }; 246 | 247 | /** 248 | * Update all widgets belonging to the same group. 249 | */ 250 | var update_group_widgets = function update_group_widgets( el ) { 251 | var $widgets = $all.find( '.widget[data-reload]' ); 252 | 253 | $widgets.each(function() { 254 | var $item = jQuery( this ), 255 | $state = $item.find( 'input.csb-clone-state' ); 256 | 257 | $state.val( 'empty' ); 258 | $item.removeAttr( 'data-reload' ); 259 | window.wpWidgets.save( $item, 0, 0, 0 ); 260 | }); 261 | }; 262 | 263 | /** 264 | * Global ajax observer reacts to all ajax responses. We need this to find 265 | * out when a new widget is saved for the first time. 266 | */ 267 | var ajax_observer = function ajax_observer( ev, xhr, opt, resp ) { 268 | var data = ( 'string' === typeof opt.data ? opt.data : '' ), 269 | find_action = data.match( /^.*&action=([^&]+).*$/ ), 270 | find_widget = data.match( /^.*&widget-id=([^&]+).*$/ ), 271 | action = (find_action && find_action.length === 2 ? find_action[1] : ''), 272 | widget = (find_widget && find_widget.length === 2 ? find_widget[1] : ''); 273 | 274 | if ( ! widget.length ) { 275 | return; 276 | } 277 | 278 | var $base = jQuery( '.widget input.widget-id[value="' + widget + '"]' ), 279 | $widget = $base.closest( '.widget' ); 280 | 281 | switch ( action ) { 282 | case 'save-widget': 283 | $widget.removeClass( 'wpmui-loading' ); 284 | if ( ! resp.length ) { 285 | // Populate widget with data from group, if required. 286 | populate_widget( $widget ); 287 | } else if ( resp.match( /^deleted:/ ) ) { 288 | // Widget was deleted and is removed with animation. 289 | window.setTimeout( init_group_icons, 400 ); 290 | } else { 291 | // Existing widget was updated. 292 | init_group_icons(); 293 | update_group_widgets( $widget ); 294 | } 295 | break; 296 | 297 | default: 298 | // Unrelated ajax event. 299 | } 300 | }; 301 | 302 | 303 | $all.find( '.widget' ).each( init_widget ); 304 | $doc.on( 'widget-added', init_widget ); 305 | $doc.on( 'widget-added', update_group_counter ); 306 | $doc.ajaxSuccess( ajax_observer ); 307 | 308 | init_group_icons(); 309 | update_template_groups(); 310 | }); 311 | -------------------------------------------------------------------------------- /assets/css/cs.min.css: -------------------------------------------------------------------------------- 1 | .module-export .pro-layer{position:absolute;left:0;top:0;right:0;bottom:0;z-index:99999;background:rgba(255,255,255,.8);text-align:center;font-size:26px;font-weight:100;padding-top:120px;line-height:1.5}.module-export .pro-layer a{margin-top:20px;display:inline-block;background:#2ea2cc;color:#fafafa;text-decoration:none;padding:10px 20px;font-size:18px;font-weight:700}.module-export .pro-layer a:active,.module-export .pro-layer a:focus,.module-export .pro-layer a:hover{background:#1e8cbe;color:#fff}.frm-location .pro-layer{padding:10px;text-align:center;font-size:26px;font-weight:100;line-height:1.5}.frm-location .pro-layer a{margin-top:20px;display:inline-block;background:#2ea2cc;color:#fafafa;text-decoration:none;padding:10px 20px;font-size:18px;font-weight:700}.frm-location .pro-layer a:active,.frm-location .pro-layer a:focus,.frm-location .pro-layer a:hover{background:#1e8cbe;color:#fff}.frm-location table.form-table{margin-bottom:10px}.frm-location table.form-table td,.frm-location table.form-table th{padding:5px}.frm-location table.form-table td.num .dashicons-trash{cursor:pointer;color:#a00}.frm-location table.form-table .num{width:3em;text-align:center}.csb-pro-layer{float:left;position:relative;opacity:.5;margin-right:10px}.csb-pro-layer .pro-info{position:absolute;left:0;top:0;right:0;bottom:0;opacity:0;background:rgba(96,96,96,.75);z-index:99999;text-align:center;text-decoration:none;line-height:28px;font-size:16px;font-weight:100;color:#fff;text-decoration:underline;padding:0;margin:0;overflow:hidden}.csb-pro-layer:hover{opacity:1}.csb-pro-layer:hover .pro-info,.csb-pro-layer:hover .pro-info:active,.csb-pro-layer:hover .pro-info:focus,.csb-pro-layer:hover .pro-info:hover{line-height:48px;left:-10px;top:-10px;right:-5px;bottom:-10px;opacity:1}.csb-pro-layer .button{margin:0 5px 0 0;float:left}.csb-pro-layer .button .dashicons{line-height:26px;height:26px;float:left;margin-right:6px}#defaultsidebarspage p.submit{padding:0 0 10px;clear:both}#poststuff.defaultsdetailscontainer h2{border-bottom:0;margin-bottom:5px}#defaultsforpages,#defaultsforposts{padding:0 10px;background:#fcfcfc;overflow:hidden}.defaultsSelector{margin-bottom:30px}.cscolright{clear:right;float:right;margin:0;overflow:hidden;padding:0;width:49%}.cscolleft{margin:0;overflow:hidden;padding:0;width:49%}.widgets-php .widget-liquid-left{width:100%}.widgets-php .cs-wrap .widget-liquid-right .widget.open{z-index:9999!important}.widgets-php .widget-liquid-right{padding:0 0 75px 0;margin:-10px -214% 0 0;width:210%;background:#e4e4e4;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@media screen and (max-width:480px){.widgets-php .widget-liquid-right{width:100%}}.widgets-php .widget-liquid-right #widgets-right{margin:20px}.widgets-php .widget-liquid-right .overview{list-style:none;position:absolute;left:0;top:0;width:auto;right:0;padding-left:20px;border-left:1px solid #ddd}.widgets-php #wpcontent{position:relative}.widgets-php #wpcontent .wrap .cs-wrap{margin-right:68%;padding-top:1em;position:relative}@media screen and (max-width:480px){.widgets-php #wpcontent .wrap .cs-wrap{position:static;margin:0}}.widgets-php #wpcontent #screen-meta-links{position:relative;z-index:10}.widgets-php #wpcontent #screen-meta{position:relative;z-index:10}.widgets-php #widgets-left{margin-right:0!important}.widgets-php #footer{background:#fff;margin-right:0;padding-right:20px}.widgets-php .sidebars-column-1 .custom-sidebars-add-new{background-color:#fff;padding:15px}.widgets-php .sidebars-column-1 .custom-sidebars-add-new p{border-radius:4px;border:3px dashed #ddd;color:#777;cursor:pointer;font-weight:700;margin:0;padding:90px 10px;text-align:center}.widgets-php .sidebars-column-1 .inner .custom-sidebars-box{border-radius:4px;margin:55px 0 16px 0}.widgets-php .sidebars-column-1 .inner .custom-sidebars-upfront{background-color:#f9c200}.widgets-php .sidebars-column-1 .inner .custom-sidebars-upfront .cs-inner{min-height:145px;margin-right:-16px;background:url(../img/devman.png) no-repeat 100% 50%;padding:50px 120px 45px 20px}.widgets-php .sidebars-column-1 .inner .custom-sidebars-upfront .cs-inner p{font-size:1.4em;color:#000;margin-top:0}.widgets-php .sidebars-column-1 .inner .custom-sidebars-upfront .cs-inner p:last-of-type{margin-bottom:0}.widgets-php .sidebars-column-1 .inner .custom-sidebars-upfront .cs-inner .button{background-color:#00a7e6;color:#fff;font-weight:700;height:auto;padding:15px 16px;text-transform:uppercase}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup{background-color:#fff}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner{background:url(../img/hand-with-heart.png) no-repeat 100% 100%;font-size:1.2em;min-height:227px;padding-bottom:10px}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner h4,.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner p{margin:0;padding:0 120px 0 30px;font-size:1.1em}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner h4{color:#222;font-size:1.2em;padding-top:50px}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner p{color:#c1272c;padding-top:16px}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner form{border-radius:4px;background-color:#fafafa;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-ms-flex-pack:justify;justify-content:space-between;margin:24px 30px 0 30px;padding:0}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner form input{background-color:transparent;border:0;font-size:1em;margin:0;padding:10px 15px;text-align:center}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner form input[type=submit]{border-radius:0 4px 4px 0;background-color:#00a7e6;color:#fff;min-width:3em;text-transform:uppercase}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner form input[type=text]{color:#aaa;-ms-flex-positive:1;flex-grow:1}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner form input[type=text]:active{box-shadow:none}@media screen and (max-width:590px){.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner form{background-color:transparent;display:block}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner form input[type=text]{background-color:#fafafa}.widgets-php .sidebars-column-1 .inner .custom-sidebars-checkup .cs-inner form input[type=submit]{border-radius:4px;display:block;margin:10px 0 0 auto;width:auto}}#cs-options .cs-action{line-height:26px;margin-right:20px}#cs-options .cs-action.btn-export{white-space:nowrap}#cs-options .cs-filter{float:right}@media screen and (max-width:700px){#cs-options .cs-filter{float:none;margin-top:5px}}.sidebar-form{margin:0 15px}.sidebar-form label{display:block}.sidebar-form .submit{text-align:right;margin:0;padding:1em 0}.sidebar-form .description{margin-top:5px;text-align:right}.sidebar_description,.sidebar_name{width:100%}div#widgets-right .sidebar-name>h3{padding:15px}div#widgets-right .widgets-sortables .sidebar-name>h3{padding:15px 7px}.widgets-holder-wrap.closed>div:nth-child(2){display:none}#defaultsidebarspage .hndle{cursor:pointer}#customsidebarspage #col-right{width:62%}.widgets_access .widget-liquid-right{position:static}#oldbrowsererror{display:none}#defaultsidebarspage .postbox{position:static}#defaultsidebarspage .inside{position:static}body.appearance_page_customsidebars .wrap h2{float:none}body.appearance_page_customsidebars #poststuff h2{margin-top:0}.widget.ui-draggable-dragging{z-index:10001!important}.csb-more-content{display:none}.csb-has-more .csb-more-content{display:block}#cs-widgets-extra{display:none}#cs-title-options{zoom:1;background:#e8e8e8;margin:-20px -20px 0 -20px;padding:10px 20px 20px;border-bottom:1px solid #ddd}.cs-title h3{font-weight:100}.cs-title h3 .cs-icon{margin-left:10px;color:#999}.replaceable{position:relative}.replaceable .replace-marker{position:absolute;left:0;top:0;bottom:0;width:5px;margin:0 5px 0 0;border-left:2px solid #05c944;z-index:10}.replaceable .replace-marker:hover:before{content:attr(data-label);background:#333;color:#eee;font-size:13px;white-space:nowrap;padding:5px;position:absolute;top:7px;right:13px;line-height:20px}.replaceable .replace-marker:hover:after{content:'';position:absolute;top:16px;right:3px;border:6px solid transparent;border-left-color:#333}.cs-message{margin:.5em 0;padding:10px;position:absolute;left:0;right:0;box-shadow:0 1px 10px rgba(0,0,0,.2);z-index:100}.cs-message .close{position:absolute;top:.5em;right:.5em;opacity:.3;color:#000;cursor:pointer;text-decoration:none;font-size:14px;line-height:26px;width:26px;text-align:center;background:rgba(0,0,0,.1)}.cs-message .close:active,.cs-message .close:focus,.cs-message .close:hover{opacity:1}.cs-update{background:#ffffe0;border:1px solid #e6db55}.cs-error{background:#ffebe8;border:1px solid #c00}.cs-toolbar{color:#333;padding:0;background:#fcfcfc;border-top:1px solid #e5e5e5}.cs-toolbar:after{display:table;content:'';clear:both}.closed .cs-toolbar{display:none}.cs-toolbar .cs-tool{text-decoration:none;line-height:40px;height:40px;padding:0 10px;white-space:nowrap;background:#fff;position:relative;overflow:hidden}.cs-toolbar .dashicons{line-height:40px}.cs-toolbar .cs-separator{border-left:1px solid #e5e5e5;width:1px;padding:0;margin:0;height:40px;overflow:hidden;display:inline-block;color:#ddd}.cs-custom-sidebar .cs-separator,.cs-custom-sidebar .cs-tool{float:right}.cs-theme-sidebar .cs-separator,.cs-theme-sidebar .cs-tool{float:left}.cs-toolbar .delete-sidebar{color:#a00}.cs-toolbar .delete-sidebar:active,.cs-toolbar .delete-sidebar:focus,.cs-toolbar .delete-sidebar:hover{color:red}.cs-toolbar .cs-tool.btn-replaceable{color:#555}.cs-toolbar .cs-tool.btn-replaceable:hover{color:#333!important}.replaceable .cs-toolbar .cs-tool.btn-replaceable{background:#edfff3;color:#333}.replace-tip-box{float:left}.replace-tip{width:200px}.csb .button{outline:0}.csb .button-primary>.dashicons,.csb .button-secondary>.dashicons,.csb .button>.dashicons{opacity:.75;line-height:26px;margin-right:5px;transition:opacity .2s}.csb .button-primary:hover>.dashicons,.csb .button-secondary:hover>.dashicons,.csb .button:hover>.dashicons{opacity:1}.rtl div.widget-liquid-right{float:left;right:auto;left:0}.rtl.widgets-php #wpcontent .wrap .cs-wrap{margin-right:2px;margin-left:68%}.rtl.widgets-php .widget-liquid-right{margin:-10px 0 0 -214%}.rtl.widgets-php #widgets-left{margin-left:0!important}.rtl.widgets-php.folded #wpcontent,.rtl.widgets-php.folded #wpfooter{margin-left:325px;margin-right:52px}.rtl #cs-title-options h2{margin-right:5px}.rtl #cs-options .cs-filter{float:left}.rtl #cs-options .cs-action{margin-right:0;margin-left:20px}.rtl .sidebar-form .submit{text-align:left}.rtl #TB_ajaxWindowTitle{float:right}.rtl #TB_closeAjaxWindow{float:left}.csb-export-head{min-width:450px}.csb-export-head th{vertical-align:top;text-align:right;color:#679;width:150px}.csb-export-head tr:hover{background:#fafafa}.csb-export-head ul{margin:0}.csb-export-head .dashicons.hint{font-size:12px;line-height:22px}.csb-form{padding-left:15px}#poststuff .csb-form .form-buttons,#poststuff .csb-form h2,#poststuff .csb-form h3,.csb-form .form-buttons,.csb-form h2,.csb-form h3{padding-left:0;margin-left:-15px}.form-buttons{clear:both}.show-infos{position:relative;display:inline-block;margin:0 5px}h2 .show-infos{top:4px}.show-infos .export-infos{position:absolute;top:-5px;left:30px;font-size:13px;line-height:1.4em;font-weight:400;background:#fff;box-shadow:0 1px 8px rgba(0,0,0,.2);border:3px solid #fafafa;padding:5px;z-index:10}.show-infos .export-infos:after,.show-infos .export-infos:before{content:'';position:absolute;left:-17px;top:5px;border:7px solid transparent;border-right-color:#fafafa;z-index:1}.show-infos .export-infos:after{left:-18px;top:5px;border-right-color:rgba(0,0,0,.15);z-index:0}.show-infos:hover .export-infos{display:block!important}.export-infos .section{font-weight:700;margin:10px 0 5px -2px;color:#666}.cs-half{float:left;width:49%;margin-right:1%}.cs-replaceable{margin-bottom:5px}.cs-replaceable>.details{display:none;margin:5px 0}.cs-replaceable.open>.details{display:block}.popup-content .message.no-sidebars{font-size:1.4em}@media screen and (max-width:480px){.wpmui-popup .buttons{height:80px;text-align:left}.wpmui-popup .buttons label{float:none;display:block;margin-bottom:.5em}.wpmui-popup .buttons .btn-save{float:right}}@media screen and (max-width:782px){#wpbody-content .wp-list-table.fixed .column-cs_replacement{display:none}}#wpbody-content .wp-list-table .column-cs_replacement{width:10%}#wpbody-content .wp-list-table .column-cs_replacement dt{opacity:.8;color:#666}#wpbody-content .wp-list-table .column-cs_replacement dd{margin-left:10px}#wpbody-content .wp-list-table .inline-edit-row fieldset.cs-quickedit{border-top:1px solid #eee;margin-top:10px;padding-top:10px}#wpbody-content .wp-list-table .inline-edit-row fieldset.cs-quickedit label span.title{display:block;float:left;min-width:5em;white-space:nowrap;padding-right:10px;width:auto}#wpbody-content .wp-list-table .inline-edit-row-page .inline-edit-col-right{float:right} -------------------------------------------------------------------------------- /views/import.php: -------------------------------------------------------------------------------- 1 | $to_id ) { 31 | $from = $theme_sidebars[ $from_id ]; 32 | $to = array(); 33 | if ( isset( $theme_sidebars[ $to_id ] ) ) { 34 | $to = $theme_sidebars[ $to_id ]; 35 | } else { 36 | $to = $import['sidebars'][ $to_id ]; 37 | } 38 | ?> 39 | 40 | 41 | 42 | 43 | 44 | 45 | 51 |
52 |
53 | 54 | 68 |

69 |
70 | 71 | 113 |
114 | 115 | 116 |
117 | 118 | 119 |
120 | 121 | 122 | 129 |

130 |

131 | 132 |

133 |

134 | 138 |

139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 168 | 169 | 172 | 173 | 174 | 175 | 188 | 189 | 217 | 218 | 221 | 222 | 223 | 224 | 237 | 238 | 242 | 243 |
170 | 171 |
244 | 250 |

 

251 |

252 |
253 | 254 | 376 |
377 |

378 | 379 |

380 | 384 |

385 | 386 | 387 |

388 | 389 | 390 |

391 | 392 |
393 | 394 | 395 |
396 |
397 | -------------------------------------------------------------------------------- /assets/js/cs.min.js: -------------------------------------------------------------------------------- 1 | /*! Custom Sidebars - v3.2.3 2 | * https://premium.wpmudev.org/project/custom-sidebars-pro/ 3 | * Copyright (c) 2019; * Licensed GPLv2+ */ 4 | 5 | function trim(a){a=a.replace(/^\s\s*/,"");for(var b=a.length-1;b>=0;b--)if(/\S/.test(a.charAt(b))){a=a.substring(0,b+1);break}return a}function CsSidebar(a,b){var c;this.id=a.split("%").join("\\%"),this.type=b,this.sb=jQuery("#"+this.id),this.widgets="",this.name=trim(this.sb.find(".sidebar-name h2").text()),this.description=trim(this.sb.find(".sidebar-description").text()),c="custom"===b?window.csSidebars.extras.find(".cs-custom-sidebar").clone():window.csSidebars.extras.find(".cs-theme-sidebar").clone(),this.sb.parent().append(c),c.find("label").each(function(){var b=jQuery(this);window.csSidebars.addIdToLabel(b,a)})}CsSidebar.prototype.getID=function(){return this.id.split("\\").join("")},window.csSidebars=null,function(a){window.csSidebars={sidebars:[],sidebar_prefix:"cs-",edit_form:null,delete_form:null,export_form:null,location_form:null,right:null,extras:null,action_handlers:{},init:function(){"undefined"!=typeof csSidebarsData&&csSidebars.initControls().initTopTools().initSidebars().initToolbars().initColumns()},initControls:function(){return csSidebars.right=jQuery("#widgets-right"),csSidebars.extras=jQuery("#cs-widgets-extra"),null===csSidebars.edit_form&&(csSidebars.edit_form=csSidebars.extras.find(".cs-editor").clone(),csSidebars.extras.find(".cs-editor").remove()),null===csSidebars.delete_form&&(csSidebars.delete_form=csSidebars.extras.find(".cs-delete").clone(),csSidebars.extras.find(".cs-delete").remove()),null===csSidebars.export_form&&(csSidebars.export_form=csSidebars.extras.find(".cs-export").clone(),csSidebars.extras.find(".cs-export").remove()),null===csSidebars.location_form&&(csSidebars.location_form=csSidebars.extras.find(".cs-location").clone(),csSidebars.extras.find(".cs-location").remove()),jQuery("#cs-title-options").detach().prependTo(csSidebars.right),csSidebars},initColumns:function(){function a(){var a=jQuery(this),b=a.closest(".sidebars-column-1, .sidebars-column-2"),c=b.data("sort-dir");c="asc"===c?"desc":"asc",csSidebars.sort_sidebars(b,c)}var b=csSidebars.right.find(".sidebars-column-1"),c=csSidebars.right.find(".sidebars-column-2"),d=jQuery('

'),e=csSidebars.right.find(".widgets-holder-wrap");c.length||(c=jQuery(''),c.appendTo(csSidebars.right)),d.find("h2").append('').css({cursor:"pointer"}),d.clone().prependTo(b).click(a).find(".cs-title-val").text(csSidebarsData.custom_sidebars),d.clone().prependTo(c).click(a).find(".cs-title-val").text(csSidebarsData.theme_sidebars),b=jQuery('
').appendTo(b),c=jQuery('
').appendTo(c),e.each(function(){var a=jQuery(this),d=a.find(".widgets-sortables");csSidebars.isCustomSidebar(d)?a.appendTo(b):a.appendTo(c)})},initSidebars:function(){return csSidebars.right.find(".widgets-sortables").each(function(){var a,b,c=!1,d=jQuery(this),e=d.attr("id");if(!0!==d.data("cs-init"))if(d.data("cs-init",!0),csSidebars.isCustomSidebar(this))b=csSidebars.add(e,"custom");else{b=csSidebars.add(e,"theme");for(a in csSidebarsData.replaceable)if(csSidebarsData.replaceable.hasOwnProperty(a)&&csSidebarsData.replaceable[a]===e){c=!0;break}csSidebars.setReplaceable(b,c,!1)}}),csSidebars},initTopTools:function(){var a=jQuery(".btn-create-sidebar"),b=jQuery(".btn-export"),c=jQuery(".cs-options"),d=jQuery(''),e={};return a.click(function(){e.id="",e.title=csSidebarsData.title_new,e.button=csSidebarsData.btn_new,e.description="",e.name="",csSidebars.showEditor(e)}),b.click(csSidebars.showExport),d.appendTo(c).attr("placeholder",csSidebarsData.filter).keyup(csSidebars.filter_sidebars).on("search",csSidebars.filter_sidebars),csSidebars},initToolbars:function(){function a(a){var b=jQuery(a.target).closest(".cs-tool"),c=b.data("action"),d=csSidebars.getIdFromEditbar(b),e=csSidebars.find(d);return!csSidebars.handleAction(c,e)}return csSidebars.registerAction("edit",csSidebars.showEditor),csSidebars.registerAction("location",csSidebars.showLocations),csSidebars.registerAction("delete",csSidebars.showRemove),csSidebars.registerAction("replaceable",csSidebars.setReplaceable),csSidebars.right.on("click",".cs-tool",a),csSidebars},handleAction:function(a,b){return"function"==typeof csSidebars.action_handlers[a]&&!!csSidebars.action_handlers[a](b)},registerAction:function(a,b){csSidebars.action_handlers[a]=b},showAjaxError:function(a){var b={};b.message=csSidebarsData.ajax_error,b.details=a,b.parent="#widgets-right",b.insert_after="#cs-title-options",b.id="editor",b.type="err",wpmUi.message(b)},sort_sidebars:function(a,b){var c=a.find(".widgets-holder-wrap"),d=a.find(".cs-title .cs-icon");c.sortElements(function(a,c){var d=jQuery(a).find(".sidebar-name h2").text(),e=jQuery(c).find(".sidebar-name h2").text();return"asc"===b?d>e?1:-1:d").attr({type:"hidden",value:"show",name:"advance"}).appendTo(a),i.loading(!0),j.reset().data(a).ondone(g).load_json(),!1}var i=null,j=null;return b instanceof CsSidebar&&(b={id:b.getID(),title:csSidebarsData.title_edit.replace("[Sidebar]",b.name),button:csSidebarsData.btn_edit}),i=wpmUi.popup().modal(!0).title(b.title).onshow(c).content(csSidebars.edit_form),c(),f(b,!0,null),j=wpmUi.ajax(null,"cs-ajax"),b.id&&(i.loading(!0),j.reset().data({do:"get",sb:b.id,_wpnonce:csSidebarsData._wpnonce_get}).ondone(f).load_json()),i.show(),i.$().find("#csb-name").focus(),i.$().on("keypress","#csb-name",function(b){13===b.keyCode&&0

').find(".description").text(b.description),csSidebars},insertSidebar:function(a){var b=jQuery('
'),c=jQuery('
'),d=jQuery(''),e=jQuery(''),f=csSidebars.right.find(".sidebars-column-1 > .inner:first");return c.attr("id",a.id),d.find("h2").text(a.name),e.html('

').find(".description").text(a.description),d.appendTo(c),e.appendTo(c),c.appendTo(b),b.prependTo(f),jQuery("#widgets-right .sidebar-name").unbind("click"),jQuery("#widgets-left .sidebar-name").unbind("click"),jQuery(document.body).unbind("click.widgets-toggle"),jQuery(".widgets-chooser").off("click.widgets-chooser").off("keyup.widgets-chooser"),jQuery("#available-widgets .widget .widget-title").off("click.widgets-chooser"),jQuery(".widgets-chooser-sidebars").empty(),window.wpWidgets.init(),csSidebars.initSidebars(),csSidebars},showExport:function(){function a(a){var b=jQuery(this).closest("form");return h.reset().data(b).load_http(),g.destroy(),a.preventDefault(),!1}function b(a,b,c){var d={};g.loading(!1),b?g.size(900,600).content(a.html):(d.message=a.message,d.parent=g.$().find(".wpmui-wnd-content"),d.insert_after=!1,d.id="export",d.class="wpmui-wnd-err",d.type="err",wpmUi.message(d))}function c(a){var c=jQuery(this).closest("form");return g.loading(!0),h.reset().data(c).ondone(b).load_json("cs-ajax"),a.preventDefault(),!1}function d(){var a=jQuery(this),b=a.prop("checked"),c=g.$().find(".column-widgets, .import-widgets");b?c.show():c.hide()}function e(){g.size(782,480),g.content(csSidebars.export_form)}function f(){var a=g.$().find(".frm-import");g.loading(!0),h.reset().data(a).load_http("_self")}var g=null,h=null;return g=wpmUi.popup().modal(!0).size(782,480).title(csSidebarsData.title_export).content(csSidebars.export_form).show(),h=wpmUi.ajax(null,"cs-ajax"),g.$().on("submit",".frm-export",a),g.$().on("submit",".frm-preview-import",c),g.$().on("change","#import-widgets",d),g.$().on("click",".btn-cancel",e),g.$().on("click",".btn-import",f),!0},showRemove:function(b){function c(a){a.find(".name").text(j)}function d(){g.loading(!1),g.destroy()}function e(a,b,c){var d={};g.loading(!1),g.destroy(),d.message=a.message,d.parent="#widgets-right",d.insert_after="#cs-title-options",d.id="editor",b?(csSidebars.right.find("#"+i).closest(".widgets-holder-wrap").remove(),csSidebars.remove(i),"delete"===a.action&&window.csSidebars.showGetStartedBox()):d.type="err",wpmUi.message(d)}function f(){g.loading(!0),h.reset().data({do:"delete",sb:i,_wpnonce:a("#_wp_nonce_cs_delete_sidebar").val()}).ondone(e).load_json()}var g=null,h=null,i=b.getID(),j=b.name;return g=wpmUi.popup().modal(!0).size(560,160).title(csSidebarsData.title_delete).content(csSidebars.delete_form).onshow(c).show(),h=wpmUi.ajax(null,"cs-ajax"),g.$().on("click",".btn-cancel",d),g.$().on("click",".btn-delete",f),!0},showLocations:function(b){function c(b,c){var d=wp.template("custom-sidebars-new-rule-row");return a("tbody",c).append(d(b)),a("tfoot",c).hide(),a("tbody .dashicons-trash",c).on("click",function(){a(this).closest("tr").detach(),0===a("tbody tr",c).length&&a("tfoot",c).show()}),!1}function d(b,d,e){function f(a,b,c){var d=jQuery("");d.attr("value",c).text(a.name),b.append(d)}function g(a,b,c,d){var e=d.closest(".cs-replaceable").filter("."+b),f=e.find('option[value="'+c+'"]'),g=e.find("optgroup.used"),h=e.find(".detail-toggle");a===l?(f.prop("selected",!0),!0!==h.prop("checked")&&(h.prop("checked",!0),e.addClass("open"),wpmUi.upgrade_multiselect(e))):(g.length||(g=jQuery('').attr("label",e.data("lbl-used")).appendTo(e.find(".details select"))),f.detach().appendTo(g))}var h,j,k;if(i.loading(!1),!d)return i.destroy(),void csSidebars.showAjaxError(b);i.$().find(".sb-name").text(b.sidebar.name);var l=b.sidebar.id;i.$().find(".message.no-sidebars").hide();var m=0,n=i.$().find(".cs-replaceable");n.hide(),b.replaceable=wpmUi.obj(b.replaceable);for(var o in b.replaceable)b.replaceable.hasOwnProperty(o)&&(n.filter("."+b.replaceable[o]).show(),m++);0===m&&(i.$().find(".wpmui-box, .message, .button-primary").hide(),i.$().find(".message.no-sidebars").show().parent().addClass("notice notice-error").removeClass("hidden"));var p=i.$().find(".cs-datalist.cs-cat"),q=i.$().find(".cs-datalist.cs-arc-cat"),r=b.categories;q.empty(),p.empty();for(var s in r)f(r[s],q,s),f(r[s],p,s);for(var t in r){if(r[t].single)for(h in r[t].single)g(r[t].single[h],h,t,p);if(r[t].archive)for(h in r[t].archive)g(r[t].archive[h],h,t,q)}var u=i.$().find(".cs-datalist.cs-pt"),v=b.posttypes;u.empty();for(var w in v)j=jQuery(""),k=v[w].name,j.attr("value",w).text(k),u.append(j);for(var x in v)if(v[x].single)for(h in v[x].single)g(v[x].single[h],h,x,u);var y=i.$().find(".cs-datalist.cs-arc"),z=b.archives;y.empty();for(var A in z)j=jQuery(""),k=z[A].name,j.attr("value",A).text(k),y.append(j);for(var B in z)if(z[B].archive)for(h in z[B].archive)g(z[B].archive[h],h,B,y);var C=i.$().find(".cs-datalist.cs-arc-aut"),D=b.authors;C.empty();for(var E in D)j=jQuery(""),k=D[E].name,j.attr("value",E).text(k),C.append(j);for(var F in D)if(D[F].archive)for(h in D[F].archive)g(D[F].archive[h],h,F,C);i.$().find(".cs-3rd-part .cs-datalist").each(function(){var c=b[a(this).data("id")];a(this).empty();for(var d in c)j=jQuery(""),k=c[d].name,j.attr("value",d).text(k),a(this).append(j);for(var e in c)if(c[e].archive)for(h in c[e].archive)g(c[e].archive[h],h,e,a(this))}),i.$().find(".cf-custom-taxonomies .cs-datalist").each(function(){var c=b[a(this).data("id")];a(this).empty();for(var d in c)j=jQuery(""),k=c[d].name,j.attr("value",d).text(k),a(this).append(j);for(var e in c)if(c[e].single)for(h in c[e].single)g(c[e].single[h],h,e,a(this))});var G=i.$().find(".csb-media-screen-width table");a.each(b.screen,function(b,d){a.each(d,function(a,d){c({minmax:a,mode:d,size:b},G)})})}function e(a){var b=jQuery(this),c=b.closest(".cs-replaceable"),d=c.find("select");b.prop("checked")?(c.addClass("open"),wpmUi.upgrade_multiselect(c),d.trigger("change.select2")):(c.removeClass("open"),d.val([]))}function f(a,b,c){var d={};i.loading(!1),i.destroy(),d.message=a.message,d.parent="#widgets-right",d.insert_after="#cs-title-options",d.id="editor",b||(d.type="err"),wpmUi.message(d)}function g(){i.loading(!0),j.reset().data(k).ondone(f).load_json()}function h(){return c({minmax:"max",mode:"hide",size:0},a("table",a(this).parent())),!1}var i=null,j=null,k=null,l=b.getID();return i=wpmUi.popup().modal(!0).size(782,560).title(csSidebarsData.title_location).content(csSidebars.location_form).show(),i.loading(!0),k=i.$().find(".frm-location"),k.find(".sb-id").val(l),j=wpmUi.ajax(null,"cs-ajax"),j.reset().data({do:"get-location",sb:l}).ondone(d).load_json(),i.$().on("click",".detail-toggle",e),i.$().on("click",".btn-save",g),i.$().on("click",".btn-cancel",i.destroy),i.$().on("click",".btn-add-rule",h),!0},setReplaceable:function(a,b,c){function d(a,b,c){a instanceof Object&&"object"==typeof a.replaceable&&(csSidebarsData.replaceable=wpmUi.obj(a.replaceable),f.find(".widgets-sortables").each(function(){var a=!1,b=jQuery(this),c=b.attr("id"),d=csSidebars.find(c);for(var e in csSidebarsData.replaceable)if(csSidebarsData.replaceable.hasOwnProperty(e)&&csSidebarsData.replaceable[e]===c){a=!0;break}csSidebars.setReplaceable(d,a,!1)})),f.find(".cs-toolbar .chk-replaceable").prop("disabled",!1),f.find(".cs-toolbar .btn-replaceable").removeClass("wpmui-loading")}var e,f=csSidebars.right.find(".sidebars-column-2 .widgets-holder-wrap"),g=jQuery(a.sb).closest(".widgets-holder-wrap"),h=g.find(".cs-toolbar .chk-replaceable"),i=g.find(".replace-marker");g.find(".cs-toolbar .btn-replaceable");return void 0===b&&(b=h.prop("checked")),void 0===c&&(c=!0),h.data("active")!==b&&(h.data("active",b),h.prop("checked",b),b?(i.length||jQuery("
").appendTo(g).attr("data-label",csSidebarsData.lbl_replaceable).addClass("replace-marker"),g.addClass("replaceable")):(i.remove(),g.removeClass("replaceable")),c&&(f.find(".cs-toolbar .chk-replaceable").prop("disabled",!0),f.find(".cs-toolbar .btn-replaceable").addClass("wpmui-loading"),e=wpmUi.ajax(null,"cs-ajax"),e.reset().data({do:"replaceable",state:b,sb:a.getID()}).ondone(d).load_json()),!1)},find:function(a){return csSidebars.sidebars[a]},add:function(a,b){return csSidebars.sidebars[a]=new CsSidebar(a,b),csSidebars.sidebars[a]},remove:function(a){delete csSidebars.sidebars[a]},isCustomSidebar:function(a){return jQuery(a).attr("id").substr(0,csSidebars.sidebar_prefix.length)===csSidebars.sidebar_prefix},addIdToLabel:function(a,b){if(!0!==a.data("label-done")){var c=a.attr("for");a.attr("for",c+b),a.find(".has-label").attr("id",c+b),a.data("label-done",!0)}},getIdFromEditbar:function(a){return a.closest(".widgets-holder-wrap").find(".widgets-sortables:first").attr("id")},showGetStartedBox:function(){if(0===a(".sidebars-column-1 .inner .widgets-holder-wrap").length){var b=wp.template("custom-sidebars-new");a(".sidebars-column-1 .inner").before(b()),a(".custom-sidebars-add-new").on("click",function(){a("button.btn-create-sidebar").click()})}}},jQuery(function(a){a("#csfooter").hide(),a("#widgets-right").length>0&&csSidebars.init(),a(".defaultsContainer").hide(),a("#widgets-right .widgets-sortables").on("sort",function(b,c){a("#widgets-right").top;c.position.top=-a("#widgets-right").css("top")})}),jQuery(document).ready(function(a){window.setTimeout(function(){window.csSidebars.showGetStartedBox()},1e3)})}(jQuery),jQuery.fn.sortElements=function(){var a=[].sort;return function(b,c){c=c||function(){return this};var d=this.map(function(){var a=c.call(this),b=a.parentNode,d=b.insertBefore(document.createTextNode(""),a.nextSibling);return function(){if(b===this)throw new Error("You can't sort elements if any one is a descendant of another.");b.insertBefore(this,d),b.removeChild(d)}});return a.call(this,b).each(function(a){d[a].call(c.call(this))})}}(),function(a){jQuery(document).ready(function(a){a("#screen-options-wrap .cs-allow-author input[type=checkbox]").on("change",function(){var b={action:"custom_sidebars_allow_author",_wpnonce:a("#custom_sidebars_allow_author").val(),value:this.checked};a.post(ajaxurl,b)})})}(jQuery),function(a){jQuery(document).ready(function(a){a("#screen-options-wrap .cs-custom-taxonomies input[type=checkbox]").on("change",function(){var b={action:"custom_sidebars_metabox_custom_taxonomies",_wpnonce:a("#custom_sidebars_custom_taxonomies").val(),fields:{}};a("#screen-options-wrap .cs-custom-taxonomies input[type=checkbox]").each(function(){b.fields[a(this).val()]=this.checked}),a.post(ajaxurl,b)})})}(jQuery),function(a){jQuery(document).ready(function(a){a("#screen-options-wrap .cs-roles input[type=checkbox]").on("change",function(){var b={action:"custom_sidebars_metabox_roles",_wpnonce:a("#custom_sidebars_metabox_roles").val(),fields:{}};a("#screen-options-wrap .cs-roles input[type=checkbox]").each(function(){b.fields[a(this).val()]=this.checked}),a.post(ajaxurl,b)})})}(jQuery); -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | --------------------------------------------------------------------------------