Changeset 3422097
- Timestamp:
- 12/17/2025 04:11:32 PM (3 months ago)
- Location:
- awesome-footnotes
- Files:
-
- 21 edited
- 1 copied
-
tags/3.8.1/classes/controllers/class-footnotes-formatter.php (modified) (1 diff)
-
tags/3.8.3/classes/controllers/class-post-settings.php (modified) (4 diffs)
-
tags/3.8.3/classes/settings/settings-options/seo-options.php (modified) (1 diff)
-
tags/3.9.2 (copied) (copied from awesome-footnotes/trunk)
-
tags/3.9.2/awesome-footnotes.php (modified) (2 diffs)
-
tags/3.9.2/classes/controllers/class-post-settings.php (modified) (7 diffs)
-
tags/3.9.2/classes/controllers/class-toc.php (modified) (6 diffs)
-
tags/3.9.2/classes/helpers/class-settings.php (modified) (3 diffs)
-
tags/3.9.2/classes/settings/class-settings-builder.php (modified) (1 diff)
-
tags/3.9.2/classes/settings/settings-options/general-toc.php (modified) (1 diff)
-
tags/3.9.2/classes/settings/settings-options/seo-options.php (modified) (1 diff)
-
tags/3.9.2/classes/settings/settings-options/toc-post.php (modified) (1 diff)
-
tags/3.9.2/readme.txt (modified) (2 diffs)
-
trunk/awesome-footnotes.php (modified) (2 diffs)
-
trunk/classes/controllers/class-post-settings.php (modified) (7 diffs)
-
trunk/classes/controllers/class-toc.php (modified) (6 diffs)
-
trunk/classes/helpers/class-settings.php (modified) (3 diffs)
-
trunk/classes/settings/class-settings-builder.php (modified) (1 diff)
-
trunk/classes/settings/settings-options/general-toc.php (modified) (1 diff)
-
trunk/classes/settings/settings-options/seo-options.php (modified) (1 diff)
-
trunk/classes/settings/settings-options/toc-post.php (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
awesome-footnotes/tags/3.8.1/classes/controllers/class-footnotes-formatter.php
r3231265 r3422097 991 991 * @return void 992 992 * 993 * @since latest993 * @since 3.9.2 994 994 */ 995 995 public static function clear_vars() { -
awesome-footnotes/tags/3.8.3/classes/controllers/class-post-settings.php
r3366051 r3422097 266 266 * @return string - the shortened content 267 267 * 268 * @since latest268 * @since 3.9.2 269 269 */ 270 270 public static function the_short_content( $limit, ?string $content = null ) { … … 311 311 * @return string 312 312 * 313 * @since latest313 * @since 3.9.2 314 314 */ 315 315 public static function get_post_seo_title( $post ) { … … 333 333 * @return string 334 334 * 335 * @since latest335 * @since 3.9.2 336 336 */ 337 337 public static function get_meta_description( $description ) { … … 356 356 * @return string 357 357 * 358 * @since latest358 * @since 3.9.2 359 359 */ 360 360 public static function get_meta_title( $title ) { -
awesome-footnotes/tags/3.8.3/classes/settings/settings-options/seo-options.php
r3366051 r3422097 5 5 * @package awe 6 6 * 7 * @since latest7 * @since 3.9.2 8 8 */ 9 9 -
awesome-footnotes/tags/3.9.2/awesome-footnotes.php
r3398513 r3422097 13 13 * Plugin Name: Footnotes 14 14 * Description: Allows post authors to easily add and manage footnotes in posts. 15 * Version: 3.9. 115 * Version: 3.9.2 16 16 * Author: Footnotes 17 17 * Author URI: https://quotecites.com … … 29 29 } 30 30 31 define( 'AWEF_VERSION', '3.9. 1' );31 define( 'AWEF_VERSION', '3.9.2' ); 32 32 define( 'AWEF_TEXTDOMAIN', 'awesome-footnotes' ); 33 33 define( 'AWEF_NAME', 'Footnotes' ); -
awesome-footnotes/tags/3.9.2/classes/controllers/class-post-settings.php
r3398363 r3422097 31 31 public const POST_SETTINGS_NAME = '_awef_post_settings'; 32 32 public const POST_SEO_TITLE = '_awef_post_seo_title'; 33 34 /** 35 * Meta key for selected primary category. 36 */ 37 public const POST_PRIMARY_CATEGORY = '_awef_primary_category'; 33 38 34 39 /** … … 77 82 'toc_scroll_spy', 78 83 'toc_subsection_toggle', 84 'toc_show_toggle', 79 85 'toc_aria_label', 80 86 'toc_anchor_offset', … … 95 101 \add_filter( 'TieLabs/meta_title', array( __CLASS__, 'get_meta_title' ) ); 96 102 \add_filter( 'TieLabs/meta_description', array( __CLASS__, 'get_meta_description' ) ); 103 104 \add_filter( 'fast_get_primary_category', array( __CLASS__, 'get_primary_category' ) ); 105 106 \add_filter( 'get_the_excerpt', array( __CLASS__, 'get_meta_description' ), 999, 2 ); 97 107 } 98 108 … … 184 194 if ( \get_the_title( $post->ID ) === $_POST[ \AWEF_SETTINGS_NAME ]['seo_title'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 185 195 \delete_post_meta( $post_id, self::POST_SEO_TITLE ); 196 } 197 } 198 199 // Primary category selection for SEO. 200 $primary_taxonomy = self::get_primary_category_taxonomy( \get_post_type( $post_id ) ); 201 if ( $primary_taxonomy ) { 202 $primary_raw = isset( $_POST[ \AWEF_SETTINGS_NAME ]['seo_primary_category'] ) ? $_POST[ \AWEF_SETTINGS_NAME ]['seo_primary_category'] : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 203 $primary_id = (int) $primary_raw; 204 205 $assigned_terms = \wp_get_post_terms( $post_id, $primary_taxonomy, array( 'fields' => 'ids' ) ); 206 if ( \is_wp_error( $assigned_terms ) ) { 207 $assigned_terms = array(); 208 } 209 210 if ( $primary_id > 0 ) { 211 // Ensure the selected primary category is assigned to the post. 212 if ( ! in_array( $primary_id, $assigned_terms, true ) ) { 213 $assigned_terms[] = $primary_id; 214 \wp_set_post_terms( $post_id, $assigned_terms, $primary_taxonomy ); 215 } 216 \update_post_meta( $post_id, self::POST_PRIMARY_CATEGORY, $primary_id ); 217 } else { 218 \delete_post_meta( $post_id, self::POST_PRIMARY_CATEGORY ); 219 } 220 221 // If no categories remain assigned, clear primary. 222 $assigned_terms = \wp_get_post_terms( $post_id, $primary_taxonomy, array( 'fields' => 'ids' ) ); 223 if ( \is_wp_error( $assigned_terms ) || empty( $assigned_terms ) ) { 224 \delete_post_meta( $post_id, self::POST_PRIMARY_CATEGORY ); 186 225 } 187 226 } … … 304 343 } 305 344 return $global; 345 } 346 347 /** 348 * Determine the taxonomy to use for primary category selection for a post type. 349 * Prefers the built-in `category` taxonomy when available, otherwise the first 350 * hierarchical taxonomy registered for the post type. 351 * 352 * @param string $post_type Post type slug. 353 * @return string|null Taxonomy name or null when none suitable. 354 */ 355 public static function get_primary_category_taxonomy( string $post_type ): ?string { 356 $taxonomies = function_exists( 'get_object_taxonomies' ) ? (array) \get_object_taxonomies( $post_type, 'objects' ) : array(); 357 if ( empty( $taxonomies ) ) { 358 return null; 359 } 360 361 if ( isset( $taxonomies['category'] ) && $taxonomies['category'] instanceof \WP_Taxonomy ) { 362 return 'category'; 363 } 364 365 foreach ( $taxonomies as $taxonomy => $object ) { 366 if ( $object instanceof \WP_Taxonomy && $object->hierarchical ) { 367 return $taxonomy; 368 } 369 } 370 371 $first = array_key_first( $taxonomies ); 372 return $first ?: null; 373 } 374 375 /** 376 * Return the selected primary category for a post. If none is stored or the 377 * stored term is no longer assigned, falls back to the first assigned 378 * category for the post. 379 * 380 * @param int|\WP_Post $post Post ID or object. 381 * @return \WP_Term|null 382 */ 383 public static function get_primary_category( $post ) { 384 $post = \get_post( $post ); 385 386 $taxonomy = self::get_primary_category_taxonomy( $post->post_type ); 387 if ( ! $taxonomy ) { 388 return null; 389 } 390 391 $assigned_terms = \wp_get_post_terms( 392 $post->ID, 393 $taxonomy, 394 array( 395 'orderby' => 'term_order', 396 'order' => 'ASC', 397 ) 398 ); 399 if ( \is_wp_error( $assigned_terms ) ) { 400 $assigned_terms = array(); 401 } 402 403 $selected_id = (int) \get_post_meta( $post->ID, self::POST_PRIMARY_CATEGORY, true ); 404 $result = null; 405 406 if ( $selected_id > 0 ) { 407 $selected = \get_term( $selected_id, $taxonomy ); 408 if ( $selected instanceof \WP_Term && ! \is_wp_error( $selected ) ) { 409 // Only return a stored primary when the post still has some terms; 410 // if all terms were removed, treat as no primary. 411 if ( ! empty( $assigned_terms ) ) { 412 $result = $selected; 413 } 414 } 415 } 416 417 if ( null === $result && ! empty( $assigned_terms ) ) { 418 $result = $assigned_terms[0]; 419 } 420 421 /** 422 * Filter the primary category term for a post. 423 * 424 * @param \WP_Term|null $result The primary term or null. 425 * @param \WP_Post $post The post object. 426 */ 427 return apply_filters( 'awef_primary_category', $result, $post ); 306 428 } 307 429 … … 520 642 * Returns meta description for the global post. 521 643 * 522 * @param string $description - The current meta description. 644 * @param string $description - The current meta description. 645 * @param WP_Post $post - The current post object. 523 646 * 524 647 * @return string … … 526 649 * @since 3.8.3 527 650 */ 528 public static function get_meta_description( $description ) { 529 global $post; 651 public static function get_meta_description( $description, $post = null ) { 652 if ( null === $post ) { 653 global $post; 654 } 530 655 if ( $post instanceof \WP_Post ) { 531 $excerpt = \get_the_excerpt( $post ); 532 if ( ! empty( $excerpt ) ) { 656 657 // Prevent recursion when calling get_the_excerpt() by temporarily removing this filter. 658 // Re-add it with a one-time closure during the same get_the_excerpt call. 659 \remove_filter( 'get_the_excerpt', array( __CLASS__, 'get_meta_description' ), 999 ); 660 661 // Prefer manual excerpt when available, otherwise use post content. 662 $raw = ''; 663 if ( isset( $post->post_excerpt ) && '' !== trim( $post->post_excerpt ) ) { 664 $raw = (string) $post->post_excerpt; 665 // Excerpt found, use it, and bail - someone set that manually so no need to interfere. 666 667 $excerpt = \get_the_excerpt( $post ); 533 668 return $excerpt; 534 669 } else { 535 return self::the_short_content( 160 ); 536 } 670 $raw = (string) $post->post_content; 671 } 672 673 // Fall in the content, but remove what might be too much. Strip shortcodes and all HTML, then trim to words. 674 // $raw = strip_shortcodes( $raw ); 675 // $raw = wp_strip_all_tags( $raw ); 676 677 // $excerpt = \get_the_excerpt( $post ); 678 // if ( ! empty( $excerpt ) ) { 679 // return $excerpt; 680 // } else { 681 return self::the_short_content( 160, $raw ); 537 682 } 538 683 -
awesome-footnotes/tags/3.9.2/classes/controllers/class-toc.php
r3398363 r3422097 132 132 $label_show = $options['toc_label_show'] ?? __( 'show', 'awesome-footnotes' ); 133 133 $label_hide = $options['toc_label_hide'] ?? __( 'hide', 'awesome-footnotes' ); 134 $toc_bg_color = $options['toc_bg_color'] ?? ''; 135 $toc_title_color = $options['toc_title_color'] ?? ''; 136 $show_toggle = array_key_exists( 'toc_show_toggle', $options ) ? (bool) $options['toc_show_toggle'] : true; 137 $show_toggle = array_key_exists( 'toc_show_toggle', $options ) ? (bool) $options['toc_show_toggle'] : true; 134 138 $use_transition = ! empty( $options['toc_transition'] ); 135 139 $cache_ttl = isset( $options['toc_cache_ttl'] ) ? (int) $options['toc_cache_ttl'] : 86400; … … 247 251 $content_id = 'awef-toc-content-' . substr( md5( (string) wp_rand() ), 0, 8 ); 248 252 $table_of_contents = '<nav class="awef-toc-container' . ( $use_transition ? ' awef-transition' : '' ) . '" role="navigation" aria-label="' . esc_attr( $options['toc_aria_label'] ?? 'Table of contents navigation' ) . '">'; 249 $table_of_contents .= '<div class="awef-toc-title"><button type="button" class="awef-toc-toggle" aria-controls="' . $content_id . '" aria-expanded="' . ( 'expanded' === $initial_state ? 'true' : 'false' ) . '" data-show-label="' . esc_attr( $label_show ) . '" data-hide-label="' . esc_attr( $label_hide ) . '">[' . esc_html( ( 'expanded' === $initial_state ) ? $label_hide : $label_show ) . ']</button>' . esc_html( $title ) . '</div>'; 253 if ( $show_toggle ) { 254 $table_of_contents .= '<div class="awef-toc-title"><button type="button" class="awef-toc-toggle" aria-controls="' . $content_id . '" aria-expanded="' . ( 'expanded' === $initial_state ? 'true' : 'false' ) . '" data-show-label="' . esc_attr( $label_show ) . '" data-hide-label="' . esc_attr( $label_hide ) . '">[' . esc_html( ( 'expanded' === $initial_state ) ? $label_hide : $label_show ) . ']</button>' . esc_html( $title ) . '</div>'; 255 } else { 256 $table_of_contents .= '<div class="awef-toc-title">' . esc_html( $title ) . '</div>'; 257 } 250 258 $table_of_contents .= '<div id="' . $content_id . '" class="awef-toc-content' . ( 'expanded' === $initial_state ? ' awef-open' : '' ) . '">' . $toc_items . '</div></nav>'; 251 259 if ( 'before' === $position ) { … … 282 290 $base_css .= '.awef-toc-content{display:' . ( 'expanded' === $initial_state ? 'block' : 'none' ) . ';}'; 283 291 } 284 $content .= '<style>' . $base_css . '</style>'; 292 // Apply color overrides if present and valid (#RGB or #RRGGBB). 293 $override_css = ''; 294 if ( ! empty( $toc_bg_color ) && Settings::is_valid_color( $toc_bg_color ) ) { 295 $override_css .= '.awef-toc-container{background:' . esc_attr( $toc_bg_color ) . ' !important;}'; 296 } 297 if ( ! empty( $toc_title_color ) && Settings::is_valid_color( $toc_title_color ) ) { 298 $override_css .= '.awef-toc-title{color:' . esc_attr( $toc_title_color ) . ' !important;}'; 299 } 300 $content .= '<style>' . $base_css . $override_css . '</style>'; 285 301 $anchor_offset = (int) ( $options['toc_anchor_offset'] ?? 0 ); 286 302 $js_label_show = esc_js( $label_show ); … … 432 448 $label_hide = $options['toc_label_hide'] ?? __( 'hide', 'awesome-footnotes' ); 433 449 $use_transition = ! empty( $options['toc_transition'] ); 450 $toc_bg_color = $options['toc_bg_color'] ?? ''; 451 $toc_title_color = $options['toc_title_color'] ?? ''; 434 452 $aria_label = $options['toc_aria_label'] ?? 'Table of contents navigation'; 435 453 $anchor_offset = (int) ( $options['toc_anchor_offset'] ?? 0 ); … … 452 470 $content_id = 'awef-toc-content-' . substr( md5( (string) wp_rand() ), 0, 8 ); 453 471 $table_of_contents = '<nav class="awef-toc-container' . ( $use_transition ? ' awef-transition' : '' ) . '" role="navigation" aria-label="' . esc_attr( $aria_label ) . '">'; 454 $table_of_contents .= '<div class="awef-toc-title"><button type="button" class="awef-toc-toggle" aria-controls="' . $content_id . '" aria-expanded="' . ( 'expanded' === $initial_state ? 'true' : 'false' ) . '" data-show-label="' . esc_attr( $label_show ) . '" data-hide-label="' . esc_attr( $label_hide ) . '">[' . esc_html( ( 'expanded' === $initial_state ) ? $label_hide : $label_show ) . ']</button>' . esc_html( $title ) . '</div>'; 472 if ( $show_toggle ) { 473 $table_of_contents .= '<div class="awef-toc-title"><button type="button" class="awef-toc-toggle" aria-controls="' . $content_id . '" aria-expanded="' . ( 'expanded' === $initial_state ? 'true' : 'false' ) . '" data-show-label="' . esc_attr( $label_show ) . '" data-hide-label="' . esc_attr( $label_hide ) . '">[' . esc_html( ( 'expanded' === $initial_state ) ? $label_hide : $label_show ) . ']</button>' . esc_html( $title ) . '</div>'; 474 } else { 475 $table_of_contents .= '<div class="awef-toc-title">' . esc_html( $title ) . '</div>'; 476 } 455 477 $table_of_contents .= '<div id="' . $content_id . '" class="awef-toc-content' . ( 'expanded' === $initial_state ? ' awef-open' : '' ) . '">' . $toc_items . '</div></nav>'; 456 478 … … 486 508 $base_css .= '.awef-toc-content{display:' . ( 'expanded' === $initial_state ? 'block' : 'none' ) . ';}'; 487 509 } 488 $assets .= '<style>' . $base_css . '</style>'; 510 // Apply color overrides if present and valid (#RGB or #RRGGBB). 511 $override_css = ''; 512 if ( ! empty( $toc_bg_color ) && preg_match( '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/', $toc_bg_color ) ) { 513 $override_css .= '.awef-toc-container{background:' . esc_attr( $toc_bg_color ) . ' !important;}'; 514 } 515 if ( ! empty( $toc_title_color ) && preg_match( '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/', $toc_title_color ) ) { 516 $override_css .= '.awef-toc-title{color:' . esc_attr( $toc_title_color ) . ' !important;}'; 517 } 518 519 $assets .= '<style>' . $base_css . $override_css . '</style>'; 489 520 $js_label_show = esc_js( $label_show ); 490 521 $js_label_hide = esc_js( $label_hide ); -
awesome-footnotes/tags/3.9.2/classes/helpers/class-settings.php
r3398363 r3422097 200 200 $footnotes_options['toc_label_show'] = ( array_key_exists( 'toc_label_show', $post_array ) ) ? sanitize_text_field( $post_array['toc_label_show'] ) : self::get_default_options()['toc_label_show']; 201 201 $footnotes_options['toc_label_hide'] = ( array_key_exists( 'toc_label_hide', $post_array ) ) ? sanitize_text_field( $post_array['toc_label_hide'] ) : self::get_default_options()['toc_label_hide']; 202 $footnotes_options['toc_show_toggle'] = ( array_key_exists( 'toc_show_toggle', $post_array ) ) ? filter_var( $post_array['toc_show_toggle'], FILTER_VALIDATE_BOOLEAN ) : false; 203 // Color options: validate hex color values, fallback to defaults if invalid. 204 $bg_col = array_key_exists( 'toc_bg_color', $post_array ) ? sanitize_text_field( $post_array['toc_bg_color'] ) : self::get_default_options()['toc_bg_color']; 205 if ( self::is_valid_color( $bg_col ) ) { 206 $footnotes_options['toc_bg_color'] = $bg_col; 207 } else { 208 $footnotes_options['toc_bg_color'] = self::get_default_options()['toc_bg_color']; 209 } 210 211 $title_col = array_key_exists( 'toc_title_color', $post_array ) ? sanitize_text_field( $post_array['toc_title_color'] ) : self::get_default_options()['toc_title_color']; 212 if ( self::is_valid_color( $title_col ) ) { 213 $footnotes_options['toc_title_color'] = $title_col; 214 } else { 215 $footnotes_options['toc_title_color'] = self::get_default_options()['toc_title_color']; 216 } 202 217 $footnotes_options['toc_transition'] = ( array_key_exists( 'toc_transition', $post_array ) ) ? filter_var( $post_array['toc_transition'], FILTER_VALIDATE_BOOLEAN ) : false; 203 218 $footnotes_options['toc_cache_ttl'] = ( array_key_exists( 'toc_cache_ttl', $post_array ) && is_numeric( $post_array['toc_cache_ttl'] ) ) ? (int) $post_array['toc_cache_ttl'] : self::get_default_options()['toc_cache_ttl']; … … 242 257 243 258 return $footnotes_options; 259 } 260 261 /** 262 * Validate a CSS color string accepted from the admin color picker. 263 * 264 * Accepts: #RGB, #RRGGBB, #RGBA, #RRGGBBAA, rgb(...), rgba(...), hsl(...), hsla(...). 265 * 266 * @param string $color Color string. 267 * @return bool True if looks like a valid color. 268 */ 269 public static function is_valid_color( string $color ): bool { 270 $color = trim( $color ); 271 if ( $color === '' ) { 272 return false; 273 } 274 275 // Hex formats: #RGB, #RRGGBB, #RGBA, #RRGGBBAA 276 if ( preg_match( '/^#(?:[A-Fa-f0-9]{3}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/', $color ) ) { 277 return true; 278 } 279 280 // rgb()/rgba() - allow 0-255 and alpha 0..1 281 if ( preg_match( '/^rgba?\(\s*(?:\d{1,3}%?\s*,\s*){2}\d{1,3}%?(?:\s*,\s*(?:0|1|0?\.\d+))?\s*\)$/i', $color ) ) { 282 return true; 283 } 284 285 // hsl()/hsla() 286 if ( preg_match( '/^hsla?\(\s*[-+]?\d+(?:\.\d+)?(?:deg|rad|turn)?\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*(?:,\s*(?:0|1|0?\.\d+))?\s*\)$/i', $color ) ) { 287 return true; 288 } 289 290 return false; 244 291 } 245 292 … … 439 486 'toc_scroll_spy' => false, 440 487 'toc_subsection_toggle' => false, 488 'toc_show_toggle' => true, 489 'toc_bg_color' => '#f9f9f9', 490 'toc_title_color' => '#000000', 491 'toc_show_toggle' => true, 441 492 // Plugin-level: where to display the Footnotes metabox by default. 442 493 'post_types' => array( 'post', 'page' ), -
awesome-footnotes/tags/3.9.2/classes/settings/class-settings-builder.php
r3169434 r3422097 535 535 private static function color() { 536 536 537 $custom_class = ! empty( self::$settings['color_class'] ) ? self::$settings['color_class'] : 'figaroColorSelector tor';537 $custom_class = ! empty( self::$settings['color_class'] ) ? self::$settings['color_class'] : 'figaroColorSelector'; 538 538 539 539 ?> -
awesome-footnotes/tags/3.9.2/classes/settings/settings-options/general-toc.php
r3398363 r3422097 121 121 Settings::build_option( 122 122 array( 123 'name' => esc_html__( 'Show toggle button', 'awesome-footnotes' ), 124 'id' => 'toc_show_toggle', 125 'type' => 'checkbox', 126 'default' => Settings::get_current_options()['toc_show_toggle'] ?? true, 127 'hint' => esc_html__( 'When unchecked the [show]/[hide] toggle button will not be rendered; TOC will always be shown/hidden according to the initial state.', 'awesome-footnotes' ), 128 ) 129 ); 130 131 Settings::build_option( 132 array( 133 'name' => esc_html__( 'TOC Background Color', 'awesome-footnotes' ), 134 'id' => 'toc_bg_color', 135 'type' => 'color', 136 'default' => Settings::get_current_options()['toc_bg_color'] ?? '#f9f9f9', 137 'hint' => esc_html__( 'Set the background color for the TOC container (.awef-toc-container).', 'awesome-footnotes' ), 138 ) 139 ); 140 141 Settings::build_option( 142 array( 143 'name' => esc_html__( 'TOC Title Color', 'awesome-footnotes' ), 144 'id' => 'toc_title_color', 145 'type' => 'color', 146 'default' => Settings::get_current_options()['toc_title_color'] ?? '#000000', 147 'hint' => esc_html__( 'Set the text color for the TOC title (.awef-toc-title). Links are unaffected.', 'awesome-footnotes' ), 148 ) 149 ); 150 151 Settings::build_option( 152 array( 123 153 'name' => esc_html__( 'Position', 'awesome-footnotes' ), 124 154 'id' => 'toc_position', -
awesome-footnotes/tags/3.9.2/classes/settings/settings-options/seo-options.php
r3366316 r3422097 53 53 ) 54 54 ); 55 56 $primary_taxonomy = Post_Settings::get_primary_category_taxonomy( $current_post->post_type ); 57 58 if ( $primary_taxonomy ) { 59 $assigned_terms = \wp_get_post_terms( $current_post->ID, $primary_taxonomy, array( 'orderby' => 'term_order', 'order' => 'ASC' ) ); 60 if ( \is_wp_error( $assigned_terms ) ) { 61 $assigned_terms = array(); 62 } 63 64 $all_terms = \get_terms( array( 'taxonomy' => $primary_taxonomy, 'hide_empty' => false ) ); 65 if ( \is_wp_error( $all_terms ) ) { 66 $all_terms = array(); 67 } 68 69 $primary_options = array(); 70 foreach ( $assigned_terms as $term ) { 71 $primary_options[ $term->term_id ] = $term->name; 72 } 73 74 foreach ( $all_terms as $term ) { 75 if ( ! isset( $primary_options[ $term->term_id ] ) ) { 76 $primary_options[ $term->term_id ] = $term->name; 77 } 78 } 79 80 if ( ! empty( $primary_options ) ) { 81 $selected_primary = Post_Settings::get_primary_category( $current_post ); 82 $default_primary = $selected_primary ? $selected_primary->term_id : ( ! empty( $assigned_terms ) ? $assigned_terms[0]->term_id : '' ); 83 84 Settings::build_option( 85 array( 86 'name' => \esc_html__( 'Primary category', 'awesome-footnotes' ), 87 'id' => 'seo_primary_category', 88 'type' => 'select', 89 'hint' => \esc_html__( 'Choose which category should be used as the primary one for this post.', 'awesome-footnotes' ), 90 'options' => $primary_options, 91 'default' => $default_primary, 92 ) 93 ); 94 } 95 } -
awesome-footnotes/tags/3.9.2/classes/settings/settings-options/toc-post.php
r3398363 r3422097 76 76 ); 77 77 78 // Reset to default (on save, remove post-level TOC overrides and fall back to globals). 79 Settings::build_option( 80 array( 81 'name' => esc_html__( 'Reset to default (this post)', 'awesome-footnotes' ), 82 'id' => 'toc_reset_defaults', 83 'type' => 'checkbox', 84 'default' => '', 85 'hint' => '<b><i>' . esc_html__( 'Note:', 'awesome-footnotes' ) . '</i></b> ' . esc_html__( 'Turn ON and Save/Update the post to clear TOC overrides and revert to global defaults.', 'awesome-footnotes' ), 86 ) 87 ); 88 89 Settings::build_option( 90 array( 91 'title' => esc_html__( 'TOC (Per Post)', 'awesome-footnotes' ), 92 'id' => 'toc-post-settings-tab', 93 'type' => 'tab-title', 94 ) 95 ); 96 97 Settings::build_option( 98 array( 99 'title' => esc_html__( 'Settings', 'awesome-footnotes' ), 100 'id' => 'toc-post-overrides-header', 101 'type' => 'header', 102 ) 103 ); 104 105 106 // Coerce checkbox default to string '1' or '' to avoid truthy rendering issues. 107 $__awef_has_enable = array_key_exists( 'toc_enable', $__awef_overrides ); 108 $__awef_val_enable = $__awef_has_enable ? ( $__awef_overrides['toc_enable'] ?? '' ) : ( $__awef_globals['toc_enable'] ?? '' ); 109 $__awef_cb_enable = ! empty( $__awef_val_enable ) && '0' !== (string) $__awef_val_enable ? '1' : ''; 110 Settings::build_option( 111 array( 112 'name' => esc_html__( 'Enable TOC (this post)', 'awesome-footnotes' ), 113 'id' => 'toc_enable', 114 'type' => 'checkbox', 115 'default' => $__awef_cb_enable, 116 'class' => array_key_exists( 'toc_enable', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 117 'hint' => esc_html__( 'Override global toggle. Checked enables TOC rendering for this post (if headings exist).', 'awesome-footnotes' ), 118 ) 119 ); 120 121 Settings::build_option( 122 array( 123 'name' => esc_html__( 'TOC Title (this post)', 'awesome-footnotes' ), 124 'id' => 'toc_title', 125 'type' => 'text', 126 'default' => (string) ( array_key_exists( 'toc_title', $__awef_overrides ) ? ( $__awef_overrides['toc_title'] ?? '' ) : ( $__awef_globals['toc_title'] ?? '' ) ), 127 'class' => array_key_exists( 'toc_title', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 128 'hint' => esc_html__( 'Leave empty to use global title.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_title', $__awef_overrides ), 129 ) 130 ); 131 132 Settings::build_option( 133 array( 134 'name' => esc_html__( 'Heading Levels (comma separated)', 'awesome-footnotes' ), 135 'id' => 'toc_levels', 136 'type' => 'text', 137 'default' => (string) ( array_key_exists( 'toc_levels', $__awef_overrides ) ? ( $__awef_overrides['toc_levels'] ?? '' ) : ( $__awef_globals['toc_levels'] ?? '' ) ), 138 'class' => array_key_exists( 'toc_levels', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 139 'hint' => esc_html__( 'e.g. 2,3,4 to include H2-H4. Leave unchanged to inherit.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_levels', $__awef_overrides ), 140 ) 141 ); 142 143 Settings::build_option( 144 array( 145 'name' => esc_html__( 'Initial State', 'awesome-footnotes' ), 146 'id' => 'toc_initial_state', 147 'type' => 'radio', 148 'options' => array( 149 'collapsed' => esc_html__( 'Collapsed', 'awesome-footnotes' ), 150 'expanded' => esc_html__( 'Expanded', 'awesome-footnotes' ), 151 ), 152 'default' => (string) ( array_key_exists( 'toc_initial_state', $__awef_overrides ) ? ( $__awef_overrides['toc_initial_state'] ?? 'collapsed' ) : ( $__awef_globals['toc_initial_state'] ?? 'collapsed' ) ), 153 'class' => array_key_exists( 'toc_initial_state', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 154 'hint' => awef_toc_status_badge( 'toc_initial_state', $__awef_overrides ), 155 ) 156 ); 157 158 Settings::build_option( 159 array( 160 'name' => esc_html__( 'Position', 'awesome-footnotes' ), 161 'id' => 'toc_position', 162 'type' => 'radio', 163 'options' => array( 164 'before' => esc_html__( 'Before Content', 'awesome-footnotes' ), 165 'after' => esc_html__( 'After Content', 'awesome-footnotes' ), 166 ), 167 'default' => (string) ( array_key_exists( 'toc_position', $__awef_overrides ) ? ( $__awef_overrides['toc_position'] ?? 'before' ) : ( $__awef_globals['toc_position'] ?? 'before' ) ), 168 'class' => array_key_exists( 'toc_position', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 169 'hint' => awef_toc_status_badge( 'toc_position', $__awef_overrides ), 170 ) 171 ); 172 173 // Advanced Structure (per-post overrides). 174 Settings::build_option( 175 array( 176 'title' => esc_html__( 'Advanced Structure', 'awesome-footnotes' ), 177 'id' => 'toc-post-advanced-structure-header', 178 'type' => 'header', 179 ) 180 ); 181 182 $_awef_has_include_h1 = array_key_exists( 'toc_include_h1', $__awef_overrides ); 183 $_awef_val_include_h1 = $_awef_has_include_h1 ? ( $__awef_overrides['toc_include_h1'] ?? '' ) : ( $__awef_globals['toc_include_h1'] ?? '' ); 184 $_awef_cb_include_h1 = ! empty( $_awef_val_include_h1 ) && '0' !== (string) $_awef_val_include_h1 ? '1' : ''; 185 Settings::build_option( 186 array( 187 'name' => esc_html__( 'Include H1', 'awesome-footnotes' ), 188 'id' => 'toc_include_h1', 189 'type' => 'checkbox', 190 'default' => $_awef_cb_include_h1, 191 'class' => array_key_exists( 'toc_include_h1', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 192 'hint' => esc_html__( 'If enabled, top-level H1 headings inside the content are included.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_include_h1', $__awef_overrides ), 193 ) 194 ); 195 196 Settings::build_option( 197 array( 198 'name' => esc_html__( 'Additional Heading Tags', 'awesome-footnotes' ), 199 'id' => 'toc_additional_tags', 200 'type' => 'text', 201 'default' => (string) ( array_key_exists( 'toc_additional_tags', $__awef_overrides ) ? ( $__awef_overrides['toc_additional_tags'] ?? '' ) : ( $__awef_globals['toc_additional_tags'] ?? '' ) ), 202 'class' => array_key_exists( 'toc_additional_tags', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 203 'hint' => esc_html__( 'Comma separated list of extra heading tags to include (e.g. h1). Non-heading tags are ignored.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_additional_tags', $__awef_overrides ), 204 ) 205 ); 206 207 $_awef_has_scroll_spy = array_key_exists( 'toc_scroll_spy', $__awef_overrides ); 208 $_awef_val_scroll_spy = $_awef_has_scroll_spy ? ( $__awef_overrides['toc_scroll_spy'] ?? '' ) : ( $__awef_globals['toc_scroll_spy'] ?? '' ); 209 $_awef_cb_scroll_spy = ! empty( $_awef_val_scroll_spy ) && '0' !== (string) $_awef_val_scroll_spy ? '1' : ''; 210 Settings::build_option( 211 array( 212 'name' => esc_html__( 'Enable Scroll Spy', 'awesome-footnotes' ), 213 'id' => 'toc_scroll_spy', 214 'type' => 'checkbox', 215 'default' => $_awef_cb_scroll_spy, 216 'class' => array_key_exists( 'toc_scroll_spy', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 217 'hint' => esc_html__( 'Highlights the currently visible heading in the TOC while scrolling.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_scroll_spy', $__awef_overrides ), 218 ) 219 ); 220 221 $_awef_has_subsection = array_key_exists( 'toc_subsection_toggle', $__awef_overrides ); 222 $_awef_val_subsection = $_awef_has_subsection ? ( $__awef_overrides['toc_subsection_toggle'] ?? '' ) : ( $__awef_globals['toc_subsection_toggle'] ?? '' ); 223 $_awef_cb_subsection_toggle = ! empty( $_awef_val_subsection ) && '0' !== (string) $_awef_val_subsection ? '1' : ''; 224 Settings::build_option( 225 array( 226 'name' => esc_html__( 'Subsection Toggle', 'awesome-footnotes' ), 227 'id' => 'toc_subsection_toggle', 228 'type' => 'checkbox', 229 'default' => $_awef_cb_subsection_toggle, 230 'class' => array_key_exists( 'toc_subsection_toggle', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 231 'hint' => esc_html__( 'Adds collapse/expand toggle buttons to nested subsections.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_subsection_toggle', $__awef_overrides ), 232 ) 233 ); 234 235 Settings::build_option( 236 array( 237 'type' => 'hint', 238 'hint' => '<div>' . esc_html__( 'Only differences from global settings are saved. Remove a value or match the global to clear its override.', 'awesome-footnotes' ) . '</div>', 239 ) 240 ); 241 242 // Numbering and Structure. 243 $_awef_has_numbering = array_key_exists( 'toc_numbering', $__awef_overrides ); 244 $_awef_val_numbering = $_awef_has_numbering ? ( $__awef_overrides['toc_numbering'] ?? '' ) : ( $__awef_globals['toc_numbering'] ?? '' ); 245 $_awef_cb_numbering = ! empty( $_awef_val_numbering ) && '0' !== (string) $_awef_val_numbering ? '1' : ''; 246 Settings::build_option( 247 array( 248 'title' => esc_html__( 'Numbering & Structure', 'awesome-footnotes' ), 249 'id' => 'toc-post-numbering-structure-header', 250 'type' => 'header', 251 ) 252 ); 253 Settings::build_option( 254 array( 255 'name' => esc_html__( 'Show Numbering', 'awesome-footnotes' ), 256 'id' => 'toc_numbering', 257 'type' => 'checkbox', 258 'default' => $_awef_cb_numbering, 259 'class' => array_key_exists( 'toc_numbering', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 260 'hint' => esc_html__( 'Adds ordered numbering to TOC items.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_numbering', $__awef_overrides ), 261 ) 262 ); 263 Settings::build_option( 264 array( 265 'name' => esc_html__( 'Structure', 'awesome-footnotes' ), 266 'id' => 'toc_structure', 267 'type' => 'radio', 268 'options' => array( 269 'flat' => esc_html__( 'Flat list', 'awesome-footnotes' ), 270 'nested' => esc_html__( 'Nested by hierarchy', 'awesome-footnotes' ), 271 ), 272 'default' => (string) ( array_key_exists( 'toc_structure', $__awef_overrides ) ? ( $__awef_overrides['toc_structure'] ?? 'flat' ) : ( $__awef_globals['toc_structure'] ?? 'flat' ) ), 273 'class' => array_key_exists( 'toc_structure', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 274 'hint' => awef_toc_status_badge( 'toc_structure', $__awef_overrides ), 275 ) 276 ); 277 Settings::build_option( 278 array( 279 'name' => esc_html__( 'Numbering Style', 'awesome-footnotes' ), 280 'id' => 'toc_numbering_style', 281 'type' => 'radio', 282 'options' => array( 283 'simple' => esc_html__( 'Simple (1,2,3)', 'awesome-footnotes' ), 284 'hierarchical' => esc_html__( 'Hierarchical (1.1, 1.2)', 'awesome-footnotes' ), 285 ), 286 'default' => (string) ( array_key_exists( 'toc_numbering_style', $__awef_overrides ) ? ( $__awef_overrides['toc_numbering_style'] ?? 'simple' ) : ( $__awef_globals['toc_numbering_style'] ?? 'simple' ) ), 287 'class' => array_key_exists( 'toc_numbering_style', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 288 'hint' => awef_toc_status_badge( 'toc_numbering_style', $__awef_overrides ), 289 ) 290 ); 291 Settings::build_option( 292 array( 293 'name' => esc_html__( 'Hierarchical Separator', 'awesome-footnotes' ), 294 'id' => 'toc_hier_sep', 295 'type' => 'radio', 296 'options' => array( 297 '.' => esc_html__( 'Dot (.)', 'awesome-footnotes' ), 298 '-' => esc_html__( 'Dash (-)', 'awesome-footnotes' ), 299 ), 300 'default' => (string) ( array_key_exists( 'toc_hier_sep', $__awef_overrides ) ? ( $__awef_overrides['toc_hier_sep'] ?? '.' ) : ( $__awef_globals['toc_hier_sep'] ?? '.' ) ), 301 'class' => array_key_exists( 'toc_hier_sep', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 302 'hint' => awef_toc_status_badge( 'toc_hier_sep', $__awef_overrides ), 303 ) 304 ); 305 Settings::build_option( 306 array( 307 'name' => esc_html__( 'Indent Step (px)', 'awesome-footnotes' ), 308 'id' => 'toc_indent_step', 309 'type' => 'number', 310 'default' => (string) ( array_key_exists( 'toc_indent_step', $__awef_overrides ) ? ( $__awef_overrides['toc_indent_step'] ?? 15 ) : ( $__awef_globals['toc_indent_step'] ?? 15 ) ), 311 'class' => array_key_exists( 'toc_indent_step', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 312 'hint' => awef_toc_status_badge( 'toc_indent_step', $__awef_overrides ), 313 ) 314 ); 315 316 // Accessibility and Behavior. 317 Settings::build_option( 318 array( 319 'title' => esc_html__( 'Accessibility & Behavior', 'awesome-footnotes' ), 320 'id' => 'toc-post-accessibility-behavior-header', 321 'type' => 'header', 322 ) 323 ); 324 Settings::build_option( 325 array( 326 'name' => esc_html__( 'ARIA Label', 'awesome-footnotes' ), 327 'id' => 'toc_aria_label', 328 'type' => 'text', 329 'default' => (string) ( array_key_exists( 'toc_aria_label', $__awef_overrides ) ? ( $__awef_overrides['toc_aria_label'] ?? '' ) : ( $__awef_globals['toc_aria_label'] ?? '' ) ), 330 'class' => array_key_exists( 'toc_aria_label', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 331 'hint' => awef_toc_status_badge( 'toc_aria_label', $__awef_overrides ), 332 ) 333 ); 334 Settings::build_option( 335 array( 336 'name' => esc_html__( 'Anchor Offset (px)', 'awesome-footnotes' ), 337 'id' => 'toc_anchor_offset', 338 'type' => 'number', 339 'default' => (string) ( array_key_exists( 'toc_anchor_offset', $__awef_overrides ) ? ( $__awef_overrides['toc_anchor_offset'] ?? 0 ) : ( $__awef_globals['toc_anchor_offset'] ?? 0 ) ), 340 'class' => array_key_exists( 'toc_anchor_offset', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 341 'hint' => awef_toc_status_badge( 'toc_anchor_offset', $__awef_overrides ), 342 ) 343 ); 344 78 // Reset to default (on save, remove post-level TOC overrides and fall back to globals). 79 Settings::build_option( 80 array( 81 'name' => esc_html__( 'Reset to default (this post)', 'awesome-footnotes' ), 82 'id' => 'toc_reset_defaults', 83 'type' => 'checkbox', 84 'default' => '', 85 'hint' => '<b><i>' . esc_html__( 'Note:', 'awesome-footnotes' ) . '</i></b> ' . esc_html__( 'Turn ON and Save/Update the post to clear TOC overrides and revert to global defaults.', 'awesome-footnotes' ), 86 ) 87 ); 88 89 Settings::build_option( 90 array( 91 'title' => esc_html__( 'TOC (Per Post)', 'awesome-footnotes' ), 92 'id' => 'toc-post-settings-tab', 93 'type' => 'tab-title', 94 ) 95 ); 96 97 Settings::build_option( 98 array( 99 'title' => esc_html__( 'Settings', 'awesome-footnotes' ), 100 'id' => 'toc-post-overrides-header', 101 'type' => 'header', 102 ) 103 ); 104 105 106 // Coerce checkbox default to string '1' or '' to avoid truthy rendering issues. 107 $__awef_has_enable = array_key_exists( 'toc_enable', $__awef_overrides ); 108 $__awef_val_enable = $__awef_has_enable ? ( $__awef_overrides['toc_enable'] ?? '' ) : ( $__awef_globals['toc_enable'] ?? '' ); 109 $__awef_cb_enable = ! empty( $__awef_val_enable ) && '0' !== (string) $__awef_val_enable ? '1' : ''; 110 Settings::build_option( 111 array( 112 'name' => esc_html__( 'Enable TOC (this post)', 'awesome-footnotes' ), 113 'id' => 'toc_enable', 114 'type' => 'checkbox', 115 'default' => $__awef_cb_enable, 116 'class' => array_key_exists( 'toc_enable', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 117 'hint' => esc_html__( 'Override global toggle. Checked enables TOC rendering for this post (if headings exist).', 'awesome-footnotes' ), 118 ) 119 ); 120 121 Settings::build_option( 122 array( 123 'name' => esc_html__( 'TOC Title (this post)', 'awesome-footnotes' ), 124 'id' => 'toc_title', 125 'type' => 'text', 126 'default' => (string) ( array_key_exists( 'toc_title', $__awef_overrides ) ? ( $__awef_overrides['toc_title'] ?? '' ) : ( $__awef_globals['toc_title'] ?? '' ) ), 127 'class' => array_key_exists( 'toc_title', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 128 'hint' => esc_html__( 'Leave empty to use global title.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_title', $__awef_overrides ), 129 ) 130 ); 131 132 Settings::build_option( 133 array( 134 'name' => esc_html__( 'Heading Levels (comma separated)', 'awesome-footnotes' ), 135 'id' => 'toc_levels', 136 'type' => 'text', 137 'default' => (string) ( array_key_exists( 'toc_levels', $__awef_overrides ) ? ( $__awef_overrides['toc_levels'] ?? '' ) : ( $__awef_globals['toc_levels'] ?? '' ) ), 138 'class' => array_key_exists( 'toc_levels', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 139 'hint' => esc_html__( 'e.g. 2,3,4 to include H2-H4. Leave unchanged to inherit.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_levels', $__awef_overrides ), 140 ) 141 ); 142 143 Settings::build_option( 144 array( 145 'name' => esc_html__( 'Initial State', 'awesome-footnotes' ), 146 'id' => 'toc_initial_state', 147 'type' => 'radio', 148 'options' => array( 149 'collapsed' => esc_html__( 'Collapsed', 'awesome-footnotes' ), 150 'expanded' => esc_html__( 'Expanded', 'awesome-footnotes' ), 151 ), 152 'default' => (string) ( array_key_exists( 'toc_initial_state', $__awef_overrides ) ? ( $__awef_overrides['toc_initial_state'] ?? 'collapsed' ) : ( $__awef_globals['toc_initial_state'] ?? 'collapsed' ) ), 153 'class' => array_key_exists( 'toc_initial_state', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 154 'hint' => awef_toc_status_badge( 'toc_initial_state', $__awef_overrides ), 155 ) 156 ); 157 158 Settings::build_option( 159 array( 160 'name' => esc_html__( 'Position', 'awesome-footnotes' ), 161 'id' => 'toc_position', 162 'type' => 'radio', 163 'options' => array( 164 'before' => esc_html__( 'Before Content', 'awesome-footnotes' ), 165 'after' => esc_html__( 'After Content', 'awesome-footnotes' ), 166 ), 167 'default' => (string) ( array_key_exists( 'toc_position', $__awef_overrides ) ? ( $__awef_overrides['toc_position'] ?? 'before' ) : ( $__awef_globals['toc_position'] ?? 'before' ) ), 168 'class' => array_key_exists( 'toc_position', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 169 'hint' => awef_toc_status_badge( 'toc_position', $__awef_overrides ), 170 ) 171 ); 172 173 // Advanced Structure (per-post overrides). 174 Settings::build_option( 175 array( 176 'title' => esc_html__( 'Advanced Structure', 'awesome-footnotes' ), 177 'id' => 'toc-post-advanced-structure-header', 178 'type' => 'header', 179 ) 180 ); 181 182 $_awef_has_include_h1 = array_key_exists( 'toc_include_h1', $__awef_overrides ); 183 $_awef_val_include_h1 = $_awef_has_include_h1 ? ( $__awef_overrides['toc_include_h1'] ?? '' ) : ( $__awef_globals['toc_include_h1'] ?? '' ); 184 $_awef_cb_include_h1 = ! empty( $_awef_val_include_h1 ) && '0' !== (string) $_awef_val_include_h1 ? '1' : ''; 185 Settings::build_option( 186 array( 187 'name' => esc_html__( 'Include H1', 'awesome-footnotes' ), 188 'id' => 'toc_include_h1', 189 'type' => 'checkbox', 190 'default' => $_awef_cb_include_h1, 191 'class' => array_key_exists( 'toc_include_h1', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 192 'hint' => esc_html__( 'If enabled, top-level H1 headings inside the content are included.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_include_h1', $__awef_overrides ), 193 ) 194 ); 195 196 Settings::build_option( 197 array( 198 'name' => esc_html__( 'Additional Heading Tags', 'awesome-footnotes' ), 199 'id' => 'toc_additional_tags', 200 'type' => 'text', 201 'default' => (string) ( array_key_exists( 'toc_additional_tags', $__awef_overrides ) ? ( $__awef_overrides['toc_additional_tags'] ?? '' ) : ( $__awef_globals['toc_additional_tags'] ?? '' ) ), 202 'class' => array_key_exists( 'toc_additional_tags', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 203 'hint' => esc_html__( 'Comma separated list of extra heading tags to include (e.g. h1). Non-heading tags are ignored.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_additional_tags', $__awef_overrides ), 204 ) 205 ); 206 207 $_awef_has_scroll_spy = array_key_exists( 'toc_scroll_spy', $__awef_overrides ); 208 $_awef_val_scroll_spy = $_awef_has_scroll_spy ? ( $__awef_overrides['toc_scroll_spy'] ?? '' ) : ( $__awef_globals['toc_scroll_spy'] ?? '' ); 209 $_awef_cb_scroll_spy = ! empty( $_awef_val_scroll_spy ) && '0' !== (string) $_awef_val_scroll_spy ? '1' : ''; 210 Settings::build_option( 211 array( 212 'name' => esc_html__( 'Enable Scroll Spy', 'awesome-footnotes' ), 213 'id' => 'toc_scroll_spy', 214 'type' => 'checkbox', 215 'default' => $_awef_cb_scroll_spy, 216 'class' => array_key_exists( 'toc_scroll_spy', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 217 'hint' => esc_html__( 'Highlights the currently visible heading in the TOC while scrolling.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_scroll_spy', $__awef_overrides ), 218 ) 219 ); 220 221 $_awef_has_subsection = array_key_exists( 'toc_subsection_toggle', $__awef_overrides ); 222 $_awef_val_subsection = $_awef_has_subsection ? ( $__awef_overrides['toc_subsection_toggle'] ?? '' ) : ( $__awef_globals['toc_subsection_toggle'] ?? '' ); 223 $_awef_cb_subsection_toggle = ! empty( $_awef_val_subsection ) && '0' !== (string) $_awef_val_subsection ? '1' : ''; 224 Settings::build_option( 225 array( 226 'name' => esc_html__( 'Subsection Toggle', 'awesome-footnotes' ), 227 'id' => 'toc_subsection_toggle', 228 'type' => 'checkbox', 229 'default' => $_awef_cb_subsection_toggle, 230 'class' => array_key_exists( 'toc_subsection_toggle', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 231 'hint' => esc_html__( 'Adds collapse/expand toggle buttons to nested subsections.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_subsection_toggle', $__awef_overrides ), 232 ) 233 ); 234 235 Settings::build_option( 236 array( 237 'type' => 'hint', 238 'hint' => '<div>' . esc_html__( 'Only differences from global settings are saved. Remove a value or match the global to clear its override.', 'awesome-footnotes' ) . '</div>', 239 ) 240 ); 241 242 // Numbering and Structure. 243 $_awef_has_numbering = array_key_exists( 'toc_numbering', $__awef_overrides ); 244 $_awef_val_numbering = $_awef_has_numbering ? ( $__awef_overrides['toc_numbering'] ?? '' ) : ( $__awef_globals['toc_numbering'] ?? '' ); 245 $_awef_cb_numbering = ! empty( $_awef_val_numbering ) && '0' !== (string) $_awef_val_numbering ? '1' : ''; 246 Settings::build_option( 247 array( 248 'title' => esc_html__( 'Numbering & Structure', 'awesome-footnotes' ), 249 'id' => 'toc-post-numbering-structure-header', 250 'type' => 'header', 251 ) 252 ); 253 Settings::build_option( 254 array( 255 'name' => esc_html__( 'Show Numbering', 'awesome-footnotes' ), 256 'id' => 'toc_numbering', 257 'type' => 'checkbox', 258 'default' => $_awef_cb_numbering, 259 'class' => array_key_exists( 'toc_numbering', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 260 'hint' => esc_html__( 'Adds ordered numbering to TOC items.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_numbering', $__awef_overrides ), 261 ) 262 ); 263 Settings::build_option( 264 array( 265 'name' => esc_html__( 'Structure', 'awesome-footnotes' ), 266 'id' => 'toc_structure', 267 'type' => 'radio', 268 'options' => array( 269 'flat' => esc_html__( 'Flat list', 'awesome-footnotes' ), 270 'nested' => esc_html__( 'Nested by hierarchy', 'awesome-footnotes' ), 271 ), 272 'default' => (string) ( array_key_exists( 'toc_structure', $__awef_overrides ) ? ( $__awef_overrides['toc_structure'] ?? 'flat' ) : ( $__awef_globals['toc_structure'] ?? 'flat' ) ), 273 'class' => array_key_exists( 'toc_structure', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 274 'hint' => awef_toc_status_badge( 'toc_structure', $__awef_overrides ), 275 ) 276 ); 277 Settings::build_option( 278 array( 279 'name' => esc_html__( 'Numbering Style', 'awesome-footnotes' ), 280 'id' => 'toc_numbering_style', 281 'type' => 'radio', 282 'options' => array( 283 'simple' => esc_html__( 'Simple (1,2,3)', 'awesome-footnotes' ), 284 'hierarchical' => esc_html__( 'Hierarchical (1.1, 1.2)', 'awesome-footnotes' ), 285 ), 286 'default' => (string) ( array_key_exists( 'toc_numbering_style', $__awef_overrides ) ? ( $__awef_overrides['toc_numbering_style'] ?? 'simple' ) : ( $__awef_globals['toc_numbering_style'] ?? 'simple' ) ), 287 'class' => array_key_exists( 'toc_numbering_style', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 288 'hint' => awef_toc_status_badge( 'toc_numbering_style', $__awef_overrides ), 289 ) 290 ); 291 Settings::build_option( 292 array( 293 'name' => esc_html__( 'Hierarchical Separator', 'awesome-footnotes' ), 294 'id' => 'toc_hier_sep', 295 'type' => 'radio', 296 'options' => array( 297 '.' => esc_html__( 'Dot (.)', 'awesome-footnotes' ), 298 '-' => esc_html__( 'Dash (-)', 'awesome-footnotes' ), 299 ), 300 'default' => (string) ( array_key_exists( 'toc_hier_sep', $__awef_overrides ) ? ( $__awef_overrides['toc_hier_sep'] ?? '.' ) : ( $__awef_globals['toc_hier_sep'] ?? '.' ) ), 301 'class' => array_key_exists( 'toc_hier_sep', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 302 'hint' => awef_toc_status_badge( 'toc_hier_sep', $__awef_overrides ), 303 ) 304 ); 305 Settings::build_option( 306 array( 307 'name' => esc_html__( 'Indent Step (px)', 'awesome-footnotes' ), 308 'id' => 'toc_indent_step', 309 'type' => 'number', 310 'default' => (string) ( array_key_exists( 'toc_indent_step', $__awef_overrides ) ? ( $__awef_overrides['toc_indent_step'] ?? 15 ) : ( $__awef_globals['toc_indent_step'] ?? 15 ) ), 311 'class' => array_key_exists( 'toc_indent_step', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 312 'hint' => awef_toc_status_badge( 'toc_indent_step', $__awef_overrides ), 313 ) 314 ); 315 316 // Accessibility and Behavior. 317 Settings::build_option( 318 array( 319 'title' => esc_html__( 'Accessibility & Behavior', 'awesome-footnotes' ), 320 'id' => 'toc-post-accessibility-behavior-header', 321 'type' => 'header', 322 ) 323 ); 324 Settings::build_option( 325 array( 326 'name' => esc_html__( 'ARIA Label', 'awesome-footnotes' ), 327 'id' => 'toc_aria_label', 328 'type' => 'text', 329 'default' => (string) ( array_key_exists( 'toc_aria_label', $__awef_overrides ) ? ( $__awef_overrides['toc_aria_label'] ?? '' ) : ( $__awef_globals['toc_aria_label'] ?? '' ) ), 330 'class' => array_key_exists( 'toc_aria_label', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 331 'hint' => awef_toc_status_badge( 'toc_aria_label', $__awef_overrides ), 332 ) 333 ); 334 Settings::build_option( 335 array( 336 'name' => esc_html__( 'Anchor Offset (px)', 'awesome-footnotes' ), 337 'id' => 'toc_anchor_offset', 338 'type' => 'number', 339 'default' => (string) ( array_key_exists( 'toc_anchor_offset', $__awef_overrides ) ? ( $__awef_overrides['toc_anchor_offset'] ?? 0 ) : ( $__awef_globals['toc_anchor_offset'] ?? 0 ) ), 340 'class' => array_key_exists( 'toc_anchor_offset', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 341 'hint' => awef_toc_status_badge( 'toc_anchor_offset', $__awef_overrides ), 342 ) 343 ); 344 345 // Show / Hide toggle button per-post override. 346 $_awef_has_show_toggle = array_key_exists( 'toc_show_toggle', $__awef_overrides ); 347 $_awef_val_show_toggle = $_awef_has_show_toggle ? ( $__awef_overrides['toc_show_toggle'] ?? '' ) : ( $__awef_globals['toc_show_toggle'] ?? '' ); 348 $_awef_cb_show_toggle = ! empty( $_awef_val_show_toggle ) && '0' !== (string) $_awef_val_show_toggle ? '1' : ''; 349 Settings::build_option( 350 array( 351 'name' => esc_html__( 'Show toggle button (this post)', 'awesome-footnotes' ), 352 'id' => 'toc_show_toggle', 353 'type' => 'checkbox', 354 'default' => $_awef_cb_show_toggle, 355 'class' => array_key_exists( 'toc_show_toggle', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 356 'hint' => esc_html__( 'When unchecked the per-post override will hide the [show]/[hide] button for this post.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_show_toggle', $__awef_overrides ), 357 ) 358 ); 359 -
awesome-footnotes/tags/3.9.2/readme.txt
r3398513 r3422097 2 2 Tags: footnotes, formatting, notes, reference 3 3 Requires at least: 6.0 4 Tested up to: 6. 84 Tested up to: 6.9 5 5 Requires PHP: 7.4 6 Stable tag: 3.9. 16 Stable tag: 3.9.2 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 141 141 == Change Log == 142 142 143 = 3.9.2 = 144 Extended TOC options. Code optimization and bug fixes. New WordPress version support. Added primary category selector for SEO. 145 143 146 = 3.9.1 = 144 147 Code fixes. -
awesome-footnotes/trunk/awesome-footnotes.php
r3398513 r3422097 13 13 * Plugin Name: Footnotes 14 14 * Description: Allows post authors to easily add and manage footnotes in posts. 15 * Version: 3.9. 115 * Version: 3.9.2 16 16 * Author: Footnotes 17 17 * Author URI: https://quotecites.com … … 29 29 } 30 30 31 define( 'AWEF_VERSION', '3.9. 1' );31 define( 'AWEF_VERSION', '3.9.2' ); 32 32 define( 'AWEF_TEXTDOMAIN', 'awesome-footnotes' ); 33 33 define( 'AWEF_NAME', 'Footnotes' ); -
awesome-footnotes/trunk/classes/controllers/class-post-settings.php
r3398363 r3422097 31 31 public const POST_SETTINGS_NAME = '_awef_post_settings'; 32 32 public const POST_SEO_TITLE = '_awef_post_seo_title'; 33 34 /** 35 * Meta key for selected primary category. 36 */ 37 public const POST_PRIMARY_CATEGORY = '_awef_primary_category'; 33 38 34 39 /** … … 77 82 'toc_scroll_spy', 78 83 'toc_subsection_toggle', 84 'toc_show_toggle', 79 85 'toc_aria_label', 80 86 'toc_anchor_offset', … … 95 101 \add_filter( 'TieLabs/meta_title', array( __CLASS__, 'get_meta_title' ) ); 96 102 \add_filter( 'TieLabs/meta_description', array( __CLASS__, 'get_meta_description' ) ); 103 104 \add_filter( 'fast_get_primary_category', array( __CLASS__, 'get_primary_category' ) ); 105 106 \add_filter( 'get_the_excerpt', array( __CLASS__, 'get_meta_description' ), 999, 2 ); 97 107 } 98 108 … … 184 194 if ( \get_the_title( $post->ID ) === $_POST[ \AWEF_SETTINGS_NAME ]['seo_title'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 185 195 \delete_post_meta( $post_id, self::POST_SEO_TITLE ); 196 } 197 } 198 199 // Primary category selection for SEO. 200 $primary_taxonomy = self::get_primary_category_taxonomy( \get_post_type( $post_id ) ); 201 if ( $primary_taxonomy ) { 202 $primary_raw = isset( $_POST[ \AWEF_SETTINGS_NAME ]['seo_primary_category'] ) ? $_POST[ \AWEF_SETTINGS_NAME ]['seo_primary_category'] : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 203 $primary_id = (int) $primary_raw; 204 205 $assigned_terms = \wp_get_post_terms( $post_id, $primary_taxonomy, array( 'fields' => 'ids' ) ); 206 if ( \is_wp_error( $assigned_terms ) ) { 207 $assigned_terms = array(); 208 } 209 210 if ( $primary_id > 0 ) { 211 // Ensure the selected primary category is assigned to the post. 212 if ( ! in_array( $primary_id, $assigned_terms, true ) ) { 213 $assigned_terms[] = $primary_id; 214 \wp_set_post_terms( $post_id, $assigned_terms, $primary_taxonomy ); 215 } 216 \update_post_meta( $post_id, self::POST_PRIMARY_CATEGORY, $primary_id ); 217 } else { 218 \delete_post_meta( $post_id, self::POST_PRIMARY_CATEGORY ); 219 } 220 221 // If no categories remain assigned, clear primary. 222 $assigned_terms = \wp_get_post_terms( $post_id, $primary_taxonomy, array( 'fields' => 'ids' ) ); 223 if ( \is_wp_error( $assigned_terms ) || empty( $assigned_terms ) ) { 224 \delete_post_meta( $post_id, self::POST_PRIMARY_CATEGORY ); 186 225 } 187 226 } … … 304 343 } 305 344 return $global; 345 } 346 347 /** 348 * Determine the taxonomy to use for primary category selection for a post type. 349 * Prefers the built-in `category` taxonomy when available, otherwise the first 350 * hierarchical taxonomy registered for the post type. 351 * 352 * @param string $post_type Post type slug. 353 * @return string|null Taxonomy name or null when none suitable. 354 */ 355 public static function get_primary_category_taxonomy( string $post_type ): ?string { 356 $taxonomies = function_exists( 'get_object_taxonomies' ) ? (array) \get_object_taxonomies( $post_type, 'objects' ) : array(); 357 if ( empty( $taxonomies ) ) { 358 return null; 359 } 360 361 if ( isset( $taxonomies['category'] ) && $taxonomies['category'] instanceof \WP_Taxonomy ) { 362 return 'category'; 363 } 364 365 foreach ( $taxonomies as $taxonomy => $object ) { 366 if ( $object instanceof \WP_Taxonomy && $object->hierarchical ) { 367 return $taxonomy; 368 } 369 } 370 371 $first = array_key_first( $taxonomies ); 372 return $first ?: null; 373 } 374 375 /** 376 * Return the selected primary category for a post. If none is stored or the 377 * stored term is no longer assigned, falls back to the first assigned 378 * category for the post. 379 * 380 * @param int|\WP_Post $post Post ID or object. 381 * @return \WP_Term|null 382 */ 383 public static function get_primary_category( $post ) { 384 $post = \get_post( $post ); 385 386 $taxonomy = self::get_primary_category_taxonomy( $post->post_type ); 387 if ( ! $taxonomy ) { 388 return null; 389 } 390 391 $assigned_terms = \wp_get_post_terms( 392 $post->ID, 393 $taxonomy, 394 array( 395 'orderby' => 'term_order', 396 'order' => 'ASC', 397 ) 398 ); 399 if ( \is_wp_error( $assigned_terms ) ) { 400 $assigned_terms = array(); 401 } 402 403 $selected_id = (int) \get_post_meta( $post->ID, self::POST_PRIMARY_CATEGORY, true ); 404 $result = null; 405 406 if ( $selected_id > 0 ) { 407 $selected = \get_term( $selected_id, $taxonomy ); 408 if ( $selected instanceof \WP_Term && ! \is_wp_error( $selected ) ) { 409 // Only return a stored primary when the post still has some terms; 410 // if all terms were removed, treat as no primary. 411 if ( ! empty( $assigned_terms ) ) { 412 $result = $selected; 413 } 414 } 415 } 416 417 if ( null === $result && ! empty( $assigned_terms ) ) { 418 $result = $assigned_terms[0]; 419 } 420 421 /** 422 * Filter the primary category term for a post. 423 * 424 * @param \WP_Term|null $result The primary term or null. 425 * @param \WP_Post $post The post object. 426 */ 427 return apply_filters( 'awef_primary_category', $result, $post ); 306 428 } 307 429 … … 520 642 * Returns meta description for the global post. 521 643 * 522 * @param string $description - The current meta description. 644 * @param string $description - The current meta description. 645 * @param WP_Post $post - The current post object. 523 646 * 524 647 * @return string … … 526 649 * @since 3.8.3 527 650 */ 528 public static function get_meta_description( $description ) { 529 global $post; 651 public static function get_meta_description( $description, $post = null ) { 652 if ( null === $post ) { 653 global $post; 654 } 530 655 if ( $post instanceof \WP_Post ) { 531 $excerpt = \get_the_excerpt( $post ); 532 if ( ! empty( $excerpt ) ) { 656 657 // Prevent recursion when calling get_the_excerpt() by temporarily removing this filter. 658 // Re-add it with a one-time closure during the same get_the_excerpt call. 659 \remove_filter( 'get_the_excerpt', array( __CLASS__, 'get_meta_description' ), 999 ); 660 661 // Prefer manual excerpt when available, otherwise use post content. 662 $raw = ''; 663 if ( isset( $post->post_excerpt ) && '' !== trim( $post->post_excerpt ) ) { 664 $raw = (string) $post->post_excerpt; 665 // Excerpt found, use it, and bail - someone set that manually so no need to interfere. 666 667 $excerpt = \get_the_excerpt( $post ); 533 668 return $excerpt; 534 669 } else { 535 return self::the_short_content( 160 ); 536 } 670 $raw = (string) $post->post_content; 671 } 672 673 // Fall in the content, but remove what might be too much. Strip shortcodes and all HTML, then trim to words. 674 // $raw = strip_shortcodes( $raw ); 675 // $raw = wp_strip_all_tags( $raw ); 676 677 // $excerpt = \get_the_excerpt( $post ); 678 // if ( ! empty( $excerpt ) ) { 679 // return $excerpt; 680 // } else { 681 return self::the_short_content( 160, $raw ); 537 682 } 538 683 -
awesome-footnotes/trunk/classes/controllers/class-toc.php
r3398363 r3422097 132 132 $label_show = $options['toc_label_show'] ?? __( 'show', 'awesome-footnotes' ); 133 133 $label_hide = $options['toc_label_hide'] ?? __( 'hide', 'awesome-footnotes' ); 134 $toc_bg_color = $options['toc_bg_color'] ?? ''; 135 $toc_title_color = $options['toc_title_color'] ?? ''; 136 $show_toggle = array_key_exists( 'toc_show_toggle', $options ) ? (bool) $options['toc_show_toggle'] : true; 137 $show_toggle = array_key_exists( 'toc_show_toggle', $options ) ? (bool) $options['toc_show_toggle'] : true; 134 138 $use_transition = ! empty( $options['toc_transition'] ); 135 139 $cache_ttl = isset( $options['toc_cache_ttl'] ) ? (int) $options['toc_cache_ttl'] : 86400; … … 247 251 $content_id = 'awef-toc-content-' . substr( md5( (string) wp_rand() ), 0, 8 ); 248 252 $table_of_contents = '<nav class="awef-toc-container' . ( $use_transition ? ' awef-transition' : '' ) . '" role="navigation" aria-label="' . esc_attr( $options['toc_aria_label'] ?? 'Table of contents navigation' ) . '">'; 249 $table_of_contents .= '<div class="awef-toc-title"><button type="button" class="awef-toc-toggle" aria-controls="' . $content_id . '" aria-expanded="' . ( 'expanded' === $initial_state ? 'true' : 'false' ) . '" data-show-label="' . esc_attr( $label_show ) . '" data-hide-label="' . esc_attr( $label_hide ) . '">[' . esc_html( ( 'expanded' === $initial_state ) ? $label_hide : $label_show ) . ']</button>' . esc_html( $title ) . '</div>'; 253 if ( $show_toggle ) { 254 $table_of_contents .= '<div class="awef-toc-title"><button type="button" class="awef-toc-toggle" aria-controls="' . $content_id . '" aria-expanded="' . ( 'expanded' === $initial_state ? 'true' : 'false' ) . '" data-show-label="' . esc_attr( $label_show ) . '" data-hide-label="' . esc_attr( $label_hide ) . '">[' . esc_html( ( 'expanded' === $initial_state ) ? $label_hide : $label_show ) . ']</button>' . esc_html( $title ) . '</div>'; 255 } else { 256 $table_of_contents .= '<div class="awef-toc-title">' . esc_html( $title ) . '</div>'; 257 } 250 258 $table_of_contents .= '<div id="' . $content_id . '" class="awef-toc-content' . ( 'expanded' === $initial_state ? ' awef-open' : '' ) . '">' . $toc_items . '</div></nav>'; 251 259 if ( 'before' === $position ) { … … 282 290 $base_css .= '.awef-toc-content{display:' . ( 'expanded' === $initial_state ? 'block' : 'none' ) . ';}'; 283 291 } 284 $content .= '<style>' . $base_css . '</style>'; 292 // Apply color overrides if present and valid (#RGB or #RRGGBB). 293 $override_css = ''; 294 if ( ! empty( $toc_bg_color ) && Settings::is_valid_color( $toc_bg_color ) ) { 295 $override_css .= '.awef-toc-container{background:' . esc_attr( $toc_bg_color ) . ' !important;}'; 296 } 297 if ( ! empty( $toc_title_color ) && Settings::is_valid_color( $toc_title_color ) ) { 298 $override_css .= '.awef-toc-title{color:' . esc_attr( $toc_title_color ) . ' !important;}'; 299 } 300 $content .= '<style>' . $base_css . $override_css . '</style>'; 285 301 $anchor_offset = (int) ( $options['toc_anchor_offset'] ?? 0 ); 286 302 $js_label_show = esc_js( $label_show ); … … 432 448 $label_hide = $options['toc_label_hide'] ?? __( 'hide', 'awesome-footnotes' ); 433 449 $use_transition = ! empty( $options['toc_transition'] ); 450 $toc_bg_color = $options['toc_bg_color'] ?? ''; 451 $toc_title_color = $options['toc_title_color'] ?? ''; 434 452 $aria_label = $options['toc_aria_label'] ?? 'Table of contents navigation'; 435 453 $anchor_offset = (int) ( $options['toc_anchor_offset'] ?? 0 ); … … 452 470 $content_id = 'awef-toc-content-' . substr( md5( (string) wp_rand() ), 0, 8 ); 453 471 $table_of_contents = '<nav class="awef-toc-container' . ( $use_transition ? ' awef-transition' : '' ) . '" role="navigation" aria-label="' . esc_attr( $aria_label ) . '">'; 454 $table_of_contents .= '<div class="awef-toc-title"><button type="button" class="awef-toc-toggle" aria-controls="' . $content_id . '" aria-expanded="' . ( 'expanded' === $initial_state ? 'true' : 'false' ) . '" data-show-label="' . esc_attr( $label_show ) . '" data-hide-label="' . esc_attr( $label_hide ) . '">[' . esc_html( ( 'expanded' === $initial_state ) ? $label_hide : $label_show ) . ']</button>' . esc_html( $title ) . '</div>'; 472 if ( $show_toggle ) { 473 $table_of_contents .= '<div class="awef-toc-title"><button type="button" class="awef-toc-toggle" aria-controls="' . $content_id . '" aria-expanded="' . ( 'expanded' === $initial_state ? 'true' : 'false' ) . '" data-show-label="' . esc_attr( $label_show ) . '" data-hide-label="' . esc_attr( $label_hide ) . '">[' . esc_html( ( 'expanded' === $initial_state ) ? $label_hide : $label_show ) . ']</button>' . esc_html( $title ) . '</div>'; 474 } else { 475 $table_of_contents .= '<div class="awef-toc-title">' . esc_html( $title ) . '</div>'; 476 } 455 477 $table_of_contents .= '<div id="' . $content_id . '" class="awef-toc-content' . ( 'expanded' === $initial_state ? ' awef-open' : '' ) . '">' . $toc_items . '</div></nav>'; 456 478 … … 486 508 $base_css .= '.awef-toc-content{display:' . ( 'expanded' === $initial_state ? 'block' : 'none' ) . ';}'; 487 509 } 488 $assets .= '<style>' . $base_css . '</style>'; 510 // Apply color overrides if present and valid (#RGB or #RRGGBB). 511 $override_css = ''; 512 if ( ! empty( $toc_bg_color ) && preg_match( '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/', $toc_bg_color ) ) { 513 $override_css .= '.awef-toc-container{background:' . esc_attr( $toc_bg_color ) . ' !important;}'; 514 } 515 if ( ! empty( $toc_title_color ) && preg_match( '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/', $toc_title_color ) ) { 516 $override_css .= '.awef-toc-title{color:' . esc_attr( $toc_title_color ) . ' !important;}'; 517 } 518 519 $assets .= '<style>' . $base_css . $override_css . '</style>'; 489 520 $js_label_show = esc_js( $label_show ); 490 521 $js_label_hide = esc_js( $label_hide ); -
awesome-footnotes/trunk/classes/helpers/class-settings.php
r3398363 r3422097 200 200 $footnotes_options['toc_label_show'] = ( array_key_exists( 'toc_label_show', $post_array ) ) ? sanitize_text_field( $post_array['toc_label_show'] ) : self::get_default_options()['toc_label_show']; 201 201 $footnotes_options['toc_label_hide'] = ( array_key_exists( 'toc_label_hide', $post_array ) ) ? sanitize_text_field( $post_array['toc_label_hide'] ) : self::get_default_options()['toc_label_hide']; 202 $footnotes_options['toc_show_toggle'] = ( array_key_exists( 'toc_show_toggle', $post_array ) ) ? filter_var( $post_array['toc_show_toggle'], FILTER_VALIDATE_BOOLEAN ) : false; 203 // Color options: validate hex color values, fallback to defaults if invalid. 204 $bg_col = array_key_exists( 'toc_bg_color', $post_array ) ? sanitize_text_field( $post_array['toc_bg_color'] ) : self::get_default_options()['toc_bg_color']; 205 if ( self::is_valid_color( $bg_col ) ) { 206 $footnotes_options['toc_bg_color'] = $bg_col; 207 } else { 208 $footnotes_options['toc_bg_color'] = self::get_default_options()['toc_bg_color']; 209 } 210 211 $title_col = array_key_exists( 'toc_title_color', $post_array ) ? sanitize_text_field( $post_array['toc_title_color'] ) : self::get_default_options()['toc_title_color']; 212 if ( self::is_valid_color( $title_col ) ) { 213 $footnotes_options['toc_title_color'] = $title_col; 214 } else { 215 $footnotes_options['toc_title_color'] = self::get_default_options()['toc_title_color']; 216 } 202 217 $footnotes_options['toc_transition'] = ( array_key_exists( 'toc_transition', $post_array ) ) ? filter_var( $post_array['toc_transition'], FILTER_VALIDATE_BOOLEAN ) : false; 203 218 $footnotes_options['toc_cache_ttl'] = ( array_key_exists( 'toc_cache_ttl', $post_array ) && is_numeric( $post_array['toc_cache_ttl'] ) ) ? (int) $post_array['toc_cache_ttl'] : self::get_default_options()['toc_cache_ttl']; … … 242 257 243 258 return $footnotes_options; 259 } 260 261 /** 262 * Validate a CSS color string accepted from the admin color picker. 263 * 264 * Accepts: #RGB, #RRGGBB, #RGBA, #RRGGBBAA, rgb(...), rgba(...), hsl(...), hsla(...). 265 * 266 * @param string $color Color string. 267 * @return bool True if looks like a valid color. 268 */ 269 public static function is_valid_color( string $color ): bool { 270 $color = trim( $color ); 271 if ( $color === '' ) { 272 return false; 273 } 274 275 // Hex formats: #RGB, #RRGGBB, #RGBA, #RRGGBBAA 276 if ( preg_match( '/^#(?:[A-Fa-f0-9]{3}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/', $color ) ) { 277 return true; 278 } 279 280 // rgb()/rgba() - allow 0-255 and alpha 0..1 281 if ( preg_match( '/^rgba?\(\s*(?:\d{1,3}%?\s*,\s*){2}\d{1,3}%?(?:\s*,\s*(?:0|1|0?\.\d+))?\s*\)$/i', $color ) ) { 282 return true; 283 } 284 285 // hsl()/hsla() 286 if ( preg_match( '/^hsla?\(\s*[-+]?\d+(?:\.\d+)?(?:deg|rad|turn)?\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*(?:,\s*(?:0|1|0?\.\d+))?\s*\)$/i', $color ) ) { 287 return true; 288 } 289 290 return false; 244 291 } 245 292 … … 439 486 'toc_scroll_spy' => false, 440 487 'toc_subsection_toggle' => false, 488 'toc_show_toggle' => true, 489 'toc_bg_color' => '#f9f9f9', 490 'toc_title_color' => '#000000', 491 'toc_show_toggle' => true, 441 492 // Plugin-level: where to display the Footnotes metabox by default. 442 493 'post_types' => array( 'post', 'page' ), -
awesome-footnotes/trunk/classes/settings/class-settings-builder.php
r3169434 r3422097 535 535 private static function color() { 536 536 537 $custom_class = ! empty( self::$settings['color_class'] ) ? self::$settings['color_class'] : 'figaroColorSelector tor';537 $custom_class = ! empty( self::$settings['color_class'] ) ? self::$settings['color_class'] : 'figaroColorSelector'; 538 538 539 539 ?> -
awesome-footnotes/trunk/classes/settings/settings-options/general-toc.php
r3398363 r3422097 121 121 Settings::build_option( 122 122 array( 123 'name' => esc_html__( 'Show toggle button', 'awesome-footnotes' ), 124 'id' => 'toc_show_toggle', 125 'type' => 'checkbox', 126 'default' => Settings::get_current_options()['toc_show_toggle'] ?? true, 127 'hint' => esc_html__( 'When unchecked the [show]/[hide] toggle button will not be rendered; TOC will always be shown/hidden according to the initial state.', 'awesome-footnotes' ), 128 ) 129 ); 130 131 Settings::build_option( 132 array( 133 'name' => esc_html__( 'TOC Background Color', 'awesome-footnotes' ), 134 'id' => 'toc_bg_color', 135 'type' => 'color', 136 'default' => Settings::get_current_options()['toc_bg_color'] ?? '#f9f9f9', 137 'hint' => esc_html__( 'Set the background color for the TOC container (.awef-toc-container).', 'awesome-footnotes' ), 138 ) 139 ); 140 141 Settings::build_option( 142 array( 143 'name' => esc_html__( 'TOC Title Color', 'awesome-footnotes' ), 144 'id' => 'toc_title_color', 145 'type' => 'color', 146 'default' => Settings::get_current_options()['toc_title_color'] ?? '#000000', 147 'hint' => esc_html__( 'Set the text color for the TOC title (.awef-toc-title). Links are unaffected.', 'awesome-footnotes' ), 148 ) 149 ); 150 151 Settings::build_option( 152 array( 123 153 'name' => esc_html__( 'Position', 'awesome-footnotes' ), 124 154 'id' => 'toc_position', -
awesome-footnotes/trunk/classes/settings/settings-options/seo-options.php
r3366316 r3422097 53 53 ) 54 54 ); 55 56 $primary_taxonomy = Post_Settings::get_primary_category_taxonomy( $current_post->post_type ); 57 58 if ( $primary_taxonomy ) { 59 $assigned_terms = \wp_get_post_terms( $current_post->ID, $primary_taxonomy, array( 'orderby' => 'term_order', 'order' => 'ASC' ) ); 60 if ( \is_wp_error( $assigned_terms ) ) { 61 $assigned_terms = array(); 62 } 63 64 $all_terms = \get_terms( array( 'taxonomy' => $primary_taxonomy, 'hide_empty' => false ) ); 65 if ( \is_wp_error( $all_terms ) ) { 66 $all_terms = array(); 67 } 68 69 $primary_options = array(); 70 foreach ( $assigned_terms as $term ) { 71 $primary_options[ $term->term_id ] = $term->name; 72 } 73 74 foreach ( $all_terms as $term ) { 75 if ( ! isset( $primary_options[ $term->term_id ] ) ) { 76 $primary_options[ $term->term_id ] = $term->name; 77 } 78 } 79 80 if ( ! empty( $primary_options ) ) { 81 $selected_primary = Post_Settings::get_primary_category( $current_post ); 82 $default_primary = $selected_primary ? $selected_primary->term_id : ( ! empty( $assigned_terms ) ? $assigned_terms[0]->term_id : '' ); 83 84 Settings::build_option( 85 array( 86 'name' => \esc_html__( 'Primary category', 'awesome-footnotes' ), 87 'id' => 'seo_primary_category', 88 'type' => 'select', 89 'hint' => \esc_html__( 'Choose which category should be used as the primary one for this post.', 'awesome-footnotes' ), 90 'options' => $primary_options, 91 'default' => $default_primary, 92 ) 93 ); 94 } 95 } -
awesome-footnotes/trunk/classes/settings/settings-options/toc-post.php
r3398363 r3422097 76 76 ); 77 77 78 // Reset to default (on save, remove post-level TOC overrides and fall back to globals). 79 Settings::build_option( 80 array( 81 'name' => esc_html__( 'Reset to default (this post)', 'awesome-footnotes' ), 82 'id' => 'toc_reset_defaults', 83 'type' => 'checkbox', 84 'default' => '', 85 'hint' => '<b><i>' . esc_html__( 'Note:', 'awesome-footnotes' ) . '</i></b> ' . esc_html__( 'Turn ON and Save/Update the post to clear TOC overrides and revert to global defaults.', 'awesome-footnotes' ), 86 ) 87 ); 88 89 Settings::build_option( 90 array( 91 'title' => esc_html__( 'TOC (Per Post)', 'awesome-footnotes' ), 92 'id' => 'toc-post-settings-tab', 93 'type' => 'tab-title', 94 ) 95 ); 96 97 Settings::build_option( 98 array( 99 'title' => esc_html__( 'Settings', 'awesome-footnotes' ), 100 'id' => 'toc-post-overrides-header', 101 'type' => 'header', 102 ) 103 ); 104 105 106 // Coerce checkbox default to string '1' or '' to avoid truthy rendering issues. 107 $__awef_has_enable = array_key_exists( 'toc_enable', $__awef_overrides ); 108 $__awef_val_enable = $__awef_has_enable ? ( $__awef_overrides['toc_enable'] ?? '' ) : ( $__awef_globals['toc_enable'] ?? '' ); 109 $__awef_cb_enable = ! empty( $__awef_val_enable ) && '0' !== (string) $__awef_val_enable ? '1' : ''; 110 Settings::build_option( 111 array( 112 'name' => esc_html__( 'Enable TOC (this post)', 'awesome-footnotes' ), 113 'id' => 'toc_enable', 114 'type' => 'checkbox', 115 'default' => $__awef_cb_enable, 116 'class' => array_key_exists( 'toc_enable', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 117 'hint' => esc_html__( 'Override global toggle. Checked enables TOC rendering for this post (if headings exist).', 'awesome-footnotes' ), 118 ) 119 ); 120 121 Settings::build_option( 122 array( 123 'name' => esc_html__( 'TOC Title (this post)', 'awesome-footnotes' ), 124 'id' => 'toc_title', 125 'type' => 'text', 126 'default' => (string) ( array_key_exists( 'toc_title', $__awef_overrides ) ? ( $__awef_overrides['toc_title'] ?? '' ) : ( $__awef_globals['toc_title'] ?? '' ) ), 127 'class' => array_key_exists( 'toc_title', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 128 'hint' => esc_html__( 'Leave empty to use global title.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_title', $__awef_overrides ), 129 ) 130 ); 131 132 Settings::build_option( 133 array( 134 'name' => esc_html__( 'Heading Levels (comma separated)', 'awesome-footnotes' ), 135 'id' => 'toc_levels', 136 'type' => 'text', 137 'default' => (string) ( array_key_exists( 'toc_levels', $__awef_overrides ) ? ( $__awef_overrides['toc_levels'] ?? '' ) : ( $__awef_globals['toc_levels'] ?? '' ) ), 138 'class' => array_key_exists( 'toc_levels', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 139 'hint' => esc_html__( 'e.g. 2,3,4 to include H2-H4. Leave unchanged to inherit.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_levels', $__awef_overrides ), 140 ) 141 ); 142 143 Settings::build_option( 144 array( 145 'name' => esc_html__( 'Initial State', 'awesome-footnotes' ), 146 'id' => 'toc_initial_state', 147 'type' => 'radio', 148 'options' => array( 149 'collapsed' => esc_html__( 'Collapsed', 'awesome-footnotes' ), 150 'expanded' => esc_html__( 'Expanded', 'awesome-footnotes' ), 151 ), 152 'default' => (string) ( array_key_exists( 'toc_initial_state', $__awef_overrides ) ? ( $__awef_overrides['toc_initial_state'] ?? 'collapsed' ) : ( $__awef_globals['toc_initial_state'] ?? 'collapsed' ) ), 153 'class' => array_key_exists( 'toc_initial_state', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 154 'hint' => awef_toc_status_badge( 'toc_initial_state', $__awef_overrides ), 155 ) 156 ); 157 158 Settings::build_option( 159 array( 160 'name' => esc_html__( 'Position', 'awesome-footnotes' ), 161 'id' => 'toc_position', 162 'type' => 'radio', 163 'options' => array( 164 'before' => esc_html__( 'Before Content', 'awesome-footnotes' ), 165 'after' => esc_html__( 'After Content', 'awesome-footnotes' ), 166 ), 167 'default' => (string) ( array_key_exists( 'toc_position', $__awef_overrides ) ? ( $__awef_overrides['toc_position'] ?? 'before' ) : ( $__awef_globals['toc_position'] ?? 'before' ) ), 168 'class' => array_key_exists( 'toc_position', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 169 'hint' => awef_toc_status_badge( 'toc_position', $__awef_overrides ), 170 ) 171 ); 172 173 // Advanced Structure (per-post overrides). 174 Settings::build_option( 175 array( 176 'title' => esc_html__( 'Advanced Structure', 'awesome-footnotes' ), 177 'id' => 'toc-post-advanced-structure-header', 178 'type' => 'header', 179 ) 180 ); 181 182 $_awef_has_include_h1 = array_key_exists( 'toc_include_h1', $__awef_overrides ); 183 $_awef_val_include_h1 = $_awef_has_include_h1 ? ( $__awef_overrides['toc_include_h1'] ?? '' ) : ( $__awef_globals['toc_include_h1'] ?? '' ); 184 $_awef_cb_include_h1 = ! empty( $_awef_val_include_h1 ) && '0' !== (string) $_awef_val_include_h1 ? '1' : ''; 185 Settings::build_option( 186 array( 187 'name' => esc_html__( 'Include H1', 'awesome-footnotes' ), 188 'id' => 'toc_include_h1', 189 'type' => 'checkbox', 190 'default' => $_awef_cb_include_h1, 191 'class' => array_key_exists( 'toc_include_h1', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 192 'hint' => esc_html__( 'If enabled, top-level H1 headings inside the content are included.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_include_h1', $__awef_overrides ), 193 ) 194 ); 195 196 Settings::build_option( 197 array( 198 'name' => esc_html__( 'Additional Heading Tags', 'awesome-footnotes' ), 199 'id' => 'toc_additional_tags', 200 'type' => 'text', 201 'default' => (string) ( array_key_exists( 'toc_additional_tags', $__awef_overrides ) ? ( $__awef_overrides['toc_additional_tags'] ?? '' ) : ( $__awef_globals['toc_additional_tags'] ?? '' ) ), 202 'class' => array_key_exists( 'toc_additional_tags', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 203 'hint' => esc_html__( 'Comma separated list of extra heading tags to include (e.g. h1). Non-heading tags are ignored.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_additional_tags', $__awef_overrides ), 204 ) 205 ); 206 207 $_awef_has_scroll_spy = array_key_exists( 'toc_scroll_spy', $__awef_overrides ); 208 $_awef_val_scroll_spy = $_awef_has_scroll_spy ? ( $__awef_overrides['toc_scroll_spy'] ?? '' ) : ( $__awef_globals['toc_scroll_spy'] ?? '' ); 209 $_awef_cb_scroll_spy = ! empty( $_awef_val_scroll_spy ) && '0' !== (string) $_awef_val_scroll_spy ? '1' : ''; 210 Settings::build_option( 211 array( 212 'name' => esc_html__( 'Enable Scroll Spy', 'awesome-footnotes' ), 213 'id' => 'toc_scroll_spy', 214 'type' => 'checkbox', 215 'default' => $_awef_cb_scroll_spy, 216 'class' => array_key_exists( 'toc_scroll_spy', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 217 'hint' => esc_html__( 'Highlights the currently visible heading in the TOC while scrolling.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_scroll_spy', $__awef_overrides ), 218 ) 219 ); 220 221 $_awef_has_subsection = array_key_exists( 'toc_subsection_toggle', $__awef_overrides ); 222 $_awef_val_subsection = $_awef_has_subsection ? ( $__awef_overrides['toc_subsection_toggle'] ?? '' ) : ( $__awef_globals['toc_subsection_toggle'] ?? '' ); 223 $_awef_cb_subsection_toggle = ! empty( $_awef_val_subsection ) && '0' !== (string) $_awef_val_subsection ? '1' : ''; 224 Settings::build_option( 225 array( 226 'name' => esc_html__( 'Subsection Toggle', 'awesome-footnotes' ), 227 'id' => 'toc_subsection_toggle', 228 'type' => 'checkbox', 229 'default' => $_awef_cb_subsection_toggle, 230 'class' => array_key_exists( 'toc_subsection_toggle', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 231 'hint' => esc_html__( 'Adds collapse/expand toggle buttons to nested subsections.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_subsection_toggle', $__awef_overrides ), 232 ) 233 ); 234 235 Settings::build_option( 236 array( 237 'type' => 'hint', 238 'hint' => '<div>' . esc_html__( 'Only differences from global settings are saved. Remove a value or match the global to clear its override.', 'awesome-footnotes' ) . '</div>', 239 ) 240 ); 241 242 // Numbering and Structure. 243 $_awef_has_numbering = array_key_exists( 'toc_numbering', $__awef_overrides ); 244 $_awef_val_numbering = $_awef_has_numbering ? ( $__awef_overrides['toc_numbering'] ?? '' ) : ( $__awef_globals['toc_numbering'] ?? '' ); 245 $_awef_cb_numbering = ! empty( $_awef_val_numbering ) && '0' !== (string) $_awef_val_numbering ? '1' : ''; 246 Settings::build_option( 247 array( 248 'title' => esc_html__( 'Numbering & Structure', 'awesome-footnotes' ), 249 'id' => 'toc-post-numbering-structure-header', 250 'type' => 'header', 251 ) 252 ); 253 Settings::build_option( 254 array( 255 'name' => esc_html__( 'Show Numbering', 'awesome-footnotes' ), 256 'id' => 'toc_numbering', 257 'type' => 'checkbox', 258 'default' => $_awef_cb_numbering, 259 'class' => array_key_exists( 'toc_numbering', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 260 'hint' => esc_html__( 'Adds ordered numbering to TOC items.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_numbering', $__awef_overrides ), 261 ) 262 ); 263 Settings::build_option( 264 array( 265 'name' => esc_html__( 'Structure', 'awesome-footnotes' ), 266 'id' => 'toc_structure', 267 'type' => 'radio', 268 'options' => array( 269 'flat' => esc_html__( 'Flat list', 'awesome-footnotes' ), 270 'nested' => esc_html__( 'Nested by hierarchy', 'awesome-footnotes' ), 271 ), 272 'default' => (string) ( array_key_exists( 'toc_structure', $__awef_overrides ) ? ( $__awef_overrides['toc_structure'] ?? 'flat' ) : ( $__awef_globals['toc_structure'] ?? 'flat' ) ), 273 'class' => array_key_exists( 'toc_structure', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 274 'hint' => awef_toc_status_badge( 'toc_structure', $__awef_overrides ), 275 ) 276 ); 277 Settings::build_option( 278 array( 279 'name' => esc_html__( 'Numbering Style', 'awesome-footnotes' ), 280 'id' => 'toc_numbering_style', 281 'type' => 'radio', 282 'options' => array( 283 'simple' => esc_html__( 'Simple (1,2,3)', 'awesome-footnotes' ), 284 'hierarchical' => esc_html__( 'Hierarchical (1.1, 1.2)', 'awesome-footnotes' ), 285 ), 286 'default' => (string) ( array_key_exists( 'toc_numbering_style', $__awef_overrides ) ? ( $__awef_overrides['toc_numbering_style'] ?? 'simple' ) : ( $__awef_globals['toc_numbering_style'] ?? 'simple' ) ), 287 'class' => array_key_exists( 'toc_numbering_style', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 288 'hint' => awef_toc_status_badge( 'toc_numbering_style', $__awef_overrides ), 289 ) 290 ); 291 Settings::build_option( 292 array( 293 'name' => esc_html__( 'Hierarchical Separator', 'awesome-footnotes' ), 294 'id' => 'toc_hier_sep', 295 'type' => 'radio', 296 'options' => array( 297 '.' => esc_html__( 'Dot (.)', 'awesome-footnotes' ), 298 '-' => esc_html__( 'Dash (-)', 'awesome-footnotes' ), 299 ), 300 'default' => (string) ( array_key_exists( 'toc_hier_sep', $__awef_overrides ) ? ( $__awef_overrides['toc_hier_sep'] ?? '.' ) : ( $__awef_globals['toc_hier_sep'] ?? '.' ) ), 301 'class' => array_key_exists( 'toc_hier_sep', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 302 'hint' => awef_toc_status_badge( 'toc_hier_sep', $__awef_overrides ), 303 ) 304 ); 305 Settings::build_option( 306 array( 307 'name' => esc_html__( 'Indent Step (px)', 'awesome-footnotes' ), 308 'id' => 'toc_indent_step', 309 'type' => 'number', 310 'default' => (string) ( array_key_exists( 'toc_indent_step', $__awef_overrides ) ? ( $__awef_overrides['toc_indent_step'] ?? 15 ) : ( $__awef_globals['toc_indent_step'] ?? 15 ) ), 311 'class' => array_key_exists( 'toc_indent_step', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 312 'hint' => awef_toc_status_badge( 'toc_indent_step', $__awef_overrides ), 313 ) 314 ); 315 316 // Accessibility and Behavior. 317 Settings::build_option( 318 array( 319 'title' => esc_html__( 'Accessibility & Behavior', 'awesome-footnotes' ), 320 'id' => 'toc-post-accessibility-behavior-header', 321 'type' => 'header', 322 ) 323 ); 324 Settings::build_option( 325 array( 326 'name' => esc_html__( 'ARIA Label', 'awesome-footnotes' ), 327 'id' => 'toc_aria_label', 328 'type' => 'text', 329 'default' => (string) ( array_key_exists( 'toc_aria_label', $__awef_overrides ) ? ( $__awef_overrides['toc_aria_label'] ?? '' ) : ( $__awef_globals['toc_aria_label'] ?? '' ) ), 330 'class' => array_key_exists( 'toc_aria_label', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 331 'hint' => awef_toc_status_badge( 'toc_aria_label', $__awef_overrides ), 332 ) 333 ); 334 Settings::build_option( 335 array( 336 'name' => esc_html__( 'Anchor Offset (px)', 'awesome-footnotes' ), 337 'id' => 'toc_anchor_offset', 338 'type' => 'number', 339 'default' => (string) ( array_key_exists( 'toc_anchor_offset', $__awef_overrides ) ? ( $__awef_overrides['toc_anchor_offset'] ?? 0 ) : ( $__awef_globals['toc_anchor_offset'] ?? 0 ) ), 340 'class' => array_key_exists( 'toc_anchor_offset', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 341 'hint' => awef_toc_status_badge( 'toc_anchor_offset', $__awef_overrides ), 342 ) 343 ); 344 78 // Reset to default (on save, remove post-level TOC overrides and fall back to globals). 79 Settings::build_option( 80 array( 81 'name' => esc_html__( 'Reset to default (this post)', 'awesome-footnotes' ), 82 'id' => 'toc_reset_defaults', 83 'type' => 'checkbox', 84 'default' => '', 85 'hint' => '<b><i>' . esc_html__( 'Note:', 'awesome-footnotes' ) . '</i></b> ' . esc_html__( 'Turn ON and Save/Update the post to clear TOC overrides and revert to global defaults.', 'awesome-footnotes' ), 86 ) 87 ); 88 89 Settings::build_option( 90 array( 91 'title' => esc_html__( 'TOC (Per Post)', 'awesome-footnotes' ), 92 'id' => 'toc-post-settings-tab', 93 'type' => 'tab-title', 94 ) 95 ); 96 97 Settings::build_option( 98 array( 99 'title' => esc_html__( 'Settings', 'awesome-footnotes' ), 100 'id' => 'toc-post-overrides-header', 101 'type' => 'header', 102 ) 103 ); 104 105 106 // Coerce checkbox default to string '1' or '' to avoid truthy rendering issues. 107 $__awef_has_enable = array_key_exists( 'toc_enable', $__awef_overrides ); 108 $__awef_val_enable = $__awef_has_enable ? ( $__awef_overrides['toc_enable'] ?? '' ) : ( $__awef_globals['toc_enable'] ?? '' ); 109 $__awef_cb_enable = ! empty( $__awef_val_enable ) && '0' !== (string) $__awef_val_enable ? '1' : ''; 110 Settings::build_option( 111 array( 112 'name' => esc_html__( 'Enable TOC (this post)', 'awesome-footnotes' ), 113 'id' => 'toc_enable', 114 'type' => 'checkbox', 115 'default' => $__awef_cb_enable, 116 'class' => array_key_exists( 'toc_enable', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 117 'hint' => esc_html__( 'Override global toggle. Checked enables TOC rendering for this post (if headings exist).', 'awesome-footnotes' ), 118 ) 119 ); 120 121 Settings::build_option( 122 array( 123 'name' => esc_html__( 'TOC Title (this post)', 'awesome-footnotes' ), 124 'id' => 'toc_title', 125 'type' => 'text', 126 'default' => (string) ( array_key_exists( 'toc_title', $__awef_overrides ) ? ( $__awef_overrides['toc_title'] ?? '' ) : ( $__awef_globals['toc_title'] ?? '' ) ), 127 'class' => array_key_exists( 'toc_title', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 128 'hint' => esc_html__( 'Leave empty to use global title.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_title', $__awef_overrides ), 129 ) 130 ); 131 132 Settings::build_option( 133 array( 134 'name' => esc_html__( 'Heading Levels (comma separated)', 'awesome-footnotes' ), 135 'id' => 'toc_levels', 136 'type' => 'text', 137 'default' => (string) ( array_key_exists( 'toc_levels', $__awef_overrides ) ? ( $__awef_overrides['toc_levels'] ?? '' ) : ( $__awef_globals['toc_levels'] ?? '' ) ), 138 'class' => array_key_exists( 'toc_levels', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 139 'hint' => esc_html__( 'e.g. 2,3,4 to include H2-H4. Leave unchanged to inherit.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_levels', $__awef_overrides ), 140 ) 141 ); 142 143 Settings::build_option( 144 array( 145 'name' => esc_html__( 'Initial State', 'awesome-footnotes' ), 146 'id' => 'toc_initial_state', 147 'type' => 'radio', 148 'options' => array( 149 'collapsed' => esc_html__( 'Collapsed', 'awesome-footnotes' ), 150 'expanded' => esc_html__( 'Expanded', 'awesome-footnotes' ), 151 ), 152 'default' => (string) ( array_key_exists( 'toc_initial_state', $__awef_overrides ) ? ( $__awef_overrides['toc_initial_state'] ?? 'collapsed' ) : ( $__awef_globals['toc_initial_state'] ?? 'collapsed' ) ), 153 'class' => array_key_exists( 'toc_initial_state', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 154 'hint' => awef_toc_status_badge( 'toc_initial_state', $__awef_overrides ), 155 ) 156 ); 157 158 Settings::build_option( 159 array( 160 'name' => esc_html__( 'Position', 'awesome-footnotes' ), 161 'id' => 'toc_position', 162 'type' => 'radio', 163 'options' => array( 164 'before' => esc_html__( 'Before Content', 'awesome-footnotes' ), 165 'after' => esc_html__( 'After Content', 'awesome-footnotes' ), 166 ), 167 'default' => (string) ( array_key_exists( 'toc_position', $__awef_overrides ) ? ( $__awef_overrides['toc_position'] ?? 'before' ) : ( $__awef_globals['toc_position'] ?? 'before' ) ), 168 'class' => array_key_exists( 'toc_position', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 169 'hint' => awef_toc_status_badge( 'toc_position', $__awef_overrides ), 170 ) 171 ); 172 173 // Advanced Structure (per-post overrides). 174 Settings::build_option( 175 array( 176 'title' => esc_html__( 'Advanced Structure', 'awesome-footnotes' ), 177 'id' => 'toc-post-advanced-structure-header', 178 'type' => 'header', 179 ) 180 ); 181 182 $_awef_has_include_h1 = array_key_exists( 'toc_include_h1', $__awef_overrides ); 183 $_awef_val_include_h1 = $_awef_has_include_h1 ? ( $__awef_overrides['toc_include_h1'] ?? '' ) : ( $__awef_globals['toc_include_h1'] ?? '' ); 184 $_awef_cb_include_h1 = ! empty( $_awef_val_include_h1 ) && '0' !== (string) $_awef_val_include_h1 ? '1' : ''; 185 Settings::build_option( 186 array( 187 'name' => esc_html__( 'Include H1', 'awesome-footnotes' ), 188 'id' => 'toc_include_h1', 189 'type' => 'checkbox', 190 'default' => $_awef_cb_include_h1, 191 'class' => array_key_exists( 'toc_include_h1', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 192 'hint' => esc_html__( 'If enabled, top-level H1 headings inside the content are included.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_include_h1', $__awef_overrides ), 193 ) 194 ); 195 196 Settings::build_option( 197 array( 198 'name' => esc_html__( 'Additional Heading Tags', 'awesome-footnotes' ), 199 'id' => 'toc_additional_tags', 200 'type' => 'text', 201 'default' => (string) ( array_key_exists( 'toc_additional_tags', $__awef_overrides ) ? ( $__awef_overrides['toc_additional_tags'] ?? '' ) : ( $__awef_globals['toc_additional_tags'] ?? '' ) ), 202 'class' => array_key_exists( 'toc_additional_tags', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 203 'hint' => esc_html__( 'Comma separated list of extra heading tags to include (e.g. h1). Non-heading tags are ignored.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_additional_tags', $__awef_overrides ), 204 ) 205 ); 206 207 $_awef_has_scroll_spy = array_key_exists( 'toc_scroll_spy', $__awef_overrides ); 208 $_awef_val_scroll_spy = $_awef_has_scroll_spy ? ( $__awef_overrides['toc_scroll_spy'] ?? '' ) : ( $__awef_globals['toc_scroll_spy'] ?? '' ); 209 $_awef_cb_scroll_spy = ! empty( $_awef_val_scroll_spy ) && '0' !== (string) $_awef_val_scroll_spy ? '1' : ''; 210 Settings::build_option( 211 array( 212 'name' => esc_html__( 'Enable Scroll Spy', 'awesome-footnotes' ), 213 'id' => 'toc_scroll_spy', 214 'type' => 'checkbox', 215 'default' => $_awef_cb_scroll_spy, 216 'class' => array_key_exists( 'toc_scroll_spy', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 217 'hint' => esc_html__( 'Highlights the currently visible heading in the TOC while scrolling.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_scroll_spy', $__awef_overrides ), 218 ) 219 ); 220 221 $_awef_has_subsection = array_key_exists( 'toc_subsection_toggle', $__awef_overrides ); 222 $_awef_val_subsection = $_awef_has_subsection ? ( $__awef_overrides['toc_subsection_toggle'] ?? '' ) : ( $__awef_globals['toc_subsection_toggle'] ?? '' ); 223 $_awef_cb_subsection_toggle = ! empty( $_awef_val_subsection ) && '0' !== (string) $_awef_val_subsection ? '1' : ''; 224 Settings::build_option( 225 array( 226 'name' => esc_html__( 'Subsection Toggle', 'awesome-footnotes' ), 227 'id' => 'toc_subsection_toggle', 228 'type' => 'checkbox', 229 'default' => $_awef_cb_subsection_toggle, 230 'class' => array_key_exists( 'toc_subsection_toggle', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 231 'hint' => esc_html__( 'Adds collapse/expand toggle buttons to nested subsections.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_subsection_toggle', $__awef_overrides ), 232 ) 233 ); 234 235 Settings::build_option( 236 array( 237 'type' => 'hint', 238 'hint' => '<div>' . esc_html__( 'Only differences from global settings are saved. Remove a value or match the global to clear its override.', 'awesome-footnotes' ) . '</div>', 239 ) 240 ); 241 242 // Numbering and Structure. 243 $_awef_has_numbering = array_key_exists( 'toc_numbering', $__awef_overrides ); 244 $_awef_val_numbering = $_awef_has_numbering ? ( $__awef_overrides['toc_numbering'] ?? '' ) : ( $__awef_globals['toc_numbering'] ?? '' ); 245 $_awef_cb_numbering = ! empty( $_awef_val_numbering ) && '0' !== (string) $_awef_val_numbering ? '1' : ''; 246 Settings::build_option( 247 array( 248 'title' => esc_html__( 'Numbering & Structure', 'awesome-footnotes' ), 249 'id' => 'toc-post-numbering-structure-header', 250 'type' => 'header', 251 ) 252 ); 253 Settings::build_option( 254 array( 255 'name' => esc_html__( 'Show Numbering', 'awesome-footnotes' ), 256 'id' => 'toc_numbering', 257 'type' => 'checkbox', 258 'default' => $_awef_cb_numbering, 259 'class' => array_key_exists( 'toc_numbering', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 260 'hint' => esc_html__( 'Adds ordered numbering to TOC items.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_numbering', $__awef_overrides ), 261 ) 262 ); 263 Settings::build_option( 264 array( 265 'name' => esc_html__( 'Structure', 'awesome-footnotes' ), 266 'id' => 'toc_structure', 267 'type' => 'radio', 268 'options' => array( 269 'flat' => esc_html__( 'Flat list', 'awesome-footnotes' ), 270 'nested' => esc_html__( 'Nested by hierarchy', 'awesome-footnotes' ), 271 ), 272 'default' => (string) ( array_key_exists( 'toc_structure', $__awef_overrides ) ? ( $__awef_overrides['toc_structure'] ?? 'flat' ) : ( $__awef_globals['toc_structure'] ?? 'flat' ) ), 273 'class' => array_key_exists( 'toc_structure', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 274 'hint' => awef_toc_status_badge( 'toc_structure', $__awef_overrides ), 275 ) 276 ); 277 Settings::build_option( 278 array( 279 'name' => esc_html__( 'Numbering Style', 'awesome-footnotes' ), 280 'id' => 'toc_numbering_style', 281 'type' => 'radio', 282 'options' => array( 283 'simple' => esc_html__( 'Simple (1,2,3)', 'awesome-footnotes' ), 284 'hierarchical' => esc_html__( 'Hierarchical (1.1, 1.2)', 'awesome-footnotes' ), 285 ), 286 'default' => (string) ( array_key_exists( 'toc_numbering_style', $__awef_overrides ) ? ( $__awef_overrides['toc_numbering_style'] ?? 'simple' ) : ( $__awef_globals['toc_numbering_style'] ?? 'simple' ) ), 287 'class' => array_key_exists( 'toc_numbering_style', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 288 'hint' => awef_toc_status_badge( 'toc_numbering_style', $__awef_overrides ), 289 ) 290 ); 291 Settings::build_option( 292 array( 293 'name' => esc_html__( 'Hierarchical Separator', 'awesome-footnotes' ), 294 'id' => 'toc_hier_sep', 295 'type' => 'radio', 296 'options' => array( 297 '.' => esc_html__( 'Dot (.)', 'awesome-footnotes' ), 298 '-' => esc_html__( 'Dash (-)', 'awesome-footnotes' ), 299 ), 300 'default' => (string) ( array_key_exists( 'toc_hier_sep', $__awef_overrides ) ? ( $__awef_overrides['toc_hier_sep'] ?? '.' ) : ( $__awef_globals['toc_hier_sep'] ?? '.' ) ), 301 'class' => array_key_exists( 'toc_hier_sep', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 302 'hint' => awef_toc_status_badge( 'toc_hier_sep', $__awef_overrides ), 303 ) 304 ); 305 Settings::build_option( 306 array( 307 'name' => esc_html__( 'Indent Step (px)', 'awesome-footnotes' ), 308 'id' => 'toc_indent_step', 309 'type' => 'number', 310 'default' => (string) ( array_key_exists( 'toc_indent_step', $__awef_overrides ) ? ( $__awef_overrides['toc_indent_step'] ?? 15 ) : ( $__awef_globals['toc_indent_step'] ?? 15 ) ), 311 'class' => array_key_exists( 'toc_indent_step', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 312 'hint' => awef_toc_status_badge( 'toc_indent_step', $__awef_overrides ), 313 ) 314 ); 315 316 // Accessibility and Behavior. 317 Settings::build_option( 318 array( 319 'title' => esc_html__( 'Accessibility & Behavior', 'awesome-footnotes' ), 320 'id' => 'toc-post-accessibility-behavior-header', 321 'type' => 'header', 322 ) 323 ); 324 Settings::build_option( 325 array( 326 'name' => esc_html__( 'ARIA Label', 'awesome-footnotes' ), 327 'id' => 'toc_aria_label', 328 'type' => 'text', 329 'default' => (string) ( array_key_exists( 'toc_aria_label', $__awef_overrides ) ? ( $__awef_overrides['toc_aria_label'] ?? '' ) : ( $__awef_globals['toc_aria_label'] ?? '' ) ), 330 'class' => array_key_exists( 'toc_aria_label', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 331 'hint' => awef_toc_status_badge( 'toc_aria_label', $__awef_overrides ), 332 ) 333 ); 334 Settings::build_option( 335 array( 336 'name' => esc_html__( 'Anchor Offset (px)', 'awesome-footnotes' ), 337 'id' => 'toc_anchor_offset', 338 'type' => 'number', 339 'default' => (string) ( array_key_exists( 'toc_anchor_offset', $__awef_overrides ) ? ( $__awef_overrides['toc_anchor_offset'] ?? 0 ) : ( $__awef_globals['toc_anchor_offset'] ?? 0 ) ), 340 'class' => array_key_exists( 'toc_anchor_offset', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 341 'hint' => awef_toc_status_badge( 'toc_anchor_offset', $__awef_overrides ), 342 ) 343 ); 344 345 // Show / Hide toggle button per-post override. 346 $_awef_has_show_toggle = array_key_exists( 'toc_show_toggle', $__awef_overrides ); 347 $_awef_val_show_toggle = $_awef_has_show_toggle ? ( $__awef_overrides['toc_show_toggle'] ?? '' ) : ( $__awef_globals['toc_show_toggle'] ?? '' ); 348 $_awef_cb_show_toggle = ! empty( $_awef_val_show_toggle ) && '0' !== (string) $_awef_val_show_toggle ? '1' : ''; 349 Settings::build_option( 350 array( 351 'name' => esc_html__( 'Show toggle button (this post)', 'awesome-footnotes' ), 352 'id' => 'toc_show_toggle', 353 'type' => 'checkbox', 354 'default' => $_awef_cb_show_toggle, 355 'class' => array_key_exists( 'toc_show_toggle', $__awef_overrides ) ? 'awef-opt-override' : 'awef-opt-inherit', 356 'hint' => esc_html__( 'When unchecked the per-post override will hide the [show]/[hide] button for this post.', 'awesome-footnotes' ) . ' ' . awef_toc_status_badge( 'toc_show_toggle', $__awef_overrides ), 357 ) 358 ); 359 -
awesome-footnotes/trunk/readme.txt
r3398513 r3422097 2 2 Tags: footnotes, formatting, notes, reference 3 3 Requires at least: 6.0 4 Tested up to: 6. 84 Tested up to: 6.9 5 5 Requires PHP: 7.4 6 Stable tag: 3.9. 16 Stable tag: 3.9.2 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 141 141 == Change Log == 142 142 143 = 3.9.2 = 144 Extended TOC options. Code optimization and bug fixes. New WordPress version support. Added primary category selector for SEO. 145 143 146 = 3.9.1 = 144 147 Code fixes.
Note: See TracChangeset
for help on using the changeset viewer.