Changeset 3441163
- Timestamp:
- 01/16/2026 04:58:45 PM (3 months ago)
- Location:
- searchcraft/trunk
- Files:
-
- 6 edited
-
admin/class-searchcraft-admin.php (modified) (11 diffs)
-
admin/css/searchcraft-admin.css (modified) (3 diffs)
-
admin/js/searchcraft-admin.js (modified) (6 diffs)
-
admin/partials/searchcraft-admin-config-tab.php (modified) (4 diffs)
-
readme.txt (modified) (2 diffs)
-
searchcraft.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
searchcraft/trunk/admin/class-searchcraft-admin.php
r3429840 r3441163 678 678 } 679 679 680 // Save excerpt field overrides for each post type. 681 $excerpt_field_overrides = array(); 682 if ( isset( $_POST['searchcraft_excerpt_field_overrides'] ) && is_array( $_POST['searchcraft_excerpt_field_overrides'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in searchcraft_request_handler(). 683 $unslashed_overrides = wp_unslash( $_POST['searchcraft_excerpt_field_overrides'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing -- Sanitized in the next step. 684 foreach ( $unslashed_overrides as $post_type => $field_name ) { 685 $sanitized_post_type = sanitize_text_field( $post_type ); 686 $sanitized_field_name = sanitize_text_field( $field_name ); 687 // Only save non-empty values. 688 if ( ! empty( $sanitized_field_name ) ) { 689 $excerpt_field_overrides[ $sanitized_post_type ] = $sanitized_field_name; 690 } 691 } 692 } 693 680 694 // Get previous selected custom fields for comparison. 681 695 $previous_selected_custom_fields = get_option( 'searchcraft_selected_custom_fields', array() ); 682 696 if ( ! is_array( $previous_selected_custom_fields ) ) { 683 697 $previous_selected_custom_fields = array(); 698 } 699 700 // Get previous excerpt field overrides for comparison. 701 $previous_excerpt_field_overrides = get_option( 'searchcraft_excerpt_field_overrides', array() ); 702 if ( ! is_array( $previous_excerpt_field_overrides ) ) { 703 $previous_excerpt_field_overrides = array(); 684 704 } 685 705 … … 707 727 $custom_post_types_fields_changed = ( serialize( $previous_custom_post_types_with_fields ) !== serialize( $custom_post_types_with_fields ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize 708 728 $selected_custom_fields_changed = ( serialize( $previous_selected_custom_fields ) !== serialize( $selected_custom_fields ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize 729 $excerpt_field_overrides_changed = ( serialize( $previous_excerpt_field_overrides ) !== serialize( $excerpt_field_overrides ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize 709 730 710 731 // Update options after comparison. … … 713 734 update_option( 'searchcraft_custom_post_types_with_fields', $custom_post_types_with_fields ); 714 735 update_option( 'searchcraft_selected_custom_fields', $selected_custom_fields ); 736 update_option( 'searchcraft_excerpt_field_overrides', $excerpt_field_overrides ); 715 737 716 738 // Check if taxonomies have changed and need index update. 717 739 // We need to update if taxonomies changed, regardless of whether we're adding or removing them. 718 740 $taxonomies_changed = ( serialize( $previous_taxonomies ) !== serialize( $filter_taxonomies ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize 719 $needs_index_update = $taxonomies_changed || $builtin_post_types_changed || $custom_post_types_changed || $custom_post_types_fields_changed || $selected_custom_fields_changed ;741 $needs_index_update = $taxonomies_changed || $builtin_post_types_changed || $custom_post_types_changed || $custom_post_types_fields_changed || $selected_custom_fields_changed || $excerpt_field_overrides_changed; 720 742 721 743 if ( $success ) { … … 726 748 if ( $needs_index_update ) { 727 749 $all_updates_successful = true; 728 $reindex ed= false;729 $error_messages = array();750 $reindex = false; 751 $error_messages = array(); 730 752 731 753 // Update taxonomy schema if taxonomies changed. … … 737 759 $error_messages[] = 'Taxonomy schema update: ' . $index_update_result['error']; 738 760 } elseif ( $index_update_result['reindexed'] ) { 739 $reindex ed= true;761 $reindex = true; 740 762 } 741 763 } … … 753 775 $error_messages[] = 'Custom post types schema update: ' . $custom_types_update_result['error']; 754 776 } elseif ( $custom_types_update_result['reindexed'] ) { 755 $reindex ed= true;777 $reindex = true; 756 778 } 757 779 } 758 780 759 781 // Reindex if built-in post types changed. 760 if ( $builtin_post_types_changed && ! $reindex ed) {782 if ( $builtin_post_types_changed && ! $reindex ) { 761 783 $this->searchcraft_add_all_documents(); 762 $reindexed = true; 784 $reindex = true; 785 } 786 787 // Reindex if excerpt field overrides changed. 788 if ( $excerpt_field_overrides_changed && ! $reindex ) { 789 $this->searchcraft_add_all_documents(); 790 $reindex = true; 763 791 } 764 792 765 793 if ( $all_updates_successful ) { 766 794 $message = 'Configuration saved successfully.'; 767 if ( $reindex ed) {795 if ( $reindex ) { 768 796 $message .= ' Index schema updated and documents re-indexed.'; 769 797 } else { … … 1900 1928 } 1901 1929 1930 // Check if there's an excerpt field override for this post type. 1931 $excerpt_field_overrides = get_option( 'searchcraft_excerpt_field_overrides', array() ); 1932 if ( ! is_array( $excerpt_field_overrides ) ) { 1933 $excerpt_field_overrides = array(); 1934 } 1935 1936 $post_excerpt = get_the_excerpt( $post ); 1937 if ( isset( $excerpt_field_overrides[ $post->post_type ] ) && ! empty( $excerpt_field_overrides[ $post->post_type ] ) ) { 1938 $override_field = $excerpt_field_overrides[ $post->post_type ]; 1939 $custom_excerpt = get_post_meta( $post->ID, $override_field, true ); 1940 // Only use the custom field if it has a value and is a string. 1941 if ( ! empty( $custom_excerpt ) && is_string( $custom_excerpt ) ) { 1942 $post_excerpt = $custom_excerpt; 1943 } 1944 } 1945 1902 1946 // Create document. 1903 1947 $document = array( … … 1905 1949 'type' => '/' . $post->post_type, 1906 1950 'post_title' => $post->post_title, 1907 'post_excerpt' => get_the_excerpt( $post ),1951 'post_excerpt' => $post_excerpt, 1908 1952 'post_content' => $clean_content, 1909 1953 'post_author_id' => $author_ids, … … 2530 2574 'searchcraft_custom_post_types_with_fields', 2531 2575 'searchcraft_selected_custom_fields', 2576 'searchcraft_excerpt_field_overrides', 2532 2577 'searchcraft_use_publishpress_authors', 2533 2578 'searchcraft_use_molongui_authorship', … … 2773 2818 } 2774 2819 update_option( $key, $valid_custom_fields ); 2820 continue; 2821 } 2822 2823 // Special handling for excerpt field overrides. 2824 if ( 'searchcraft_excerpt_field_overrides' === $key && is_array( $value ) ) { 2825 $valid_excerpt_overrides = array(); 2826 foreach ( $value as $post_type => $field_name ) { 2827 // Only include if the post type exists. 2828 if ( post_type_exists( $post_type ) ) { 2829 // Validate that the meta key exists for this post type. 2830 $existing_meta_keys = Searchcraft_Helper_Functions::searchcraft_get_meta_keys_for_post_type( $post_type ); 2831 if ( array_key_exists( $field_name, $existing_meta_keys ) ) { 2832 $valid_excerpt_overrides[ $post_type ] = $field_name; 2833 } else { 2834 $post_type_obj = get_post_type_object( $post_type ); 2835 $post_type_label = $post_type_obj ? $post_type_obj->label : $post_type; 2836 $warnings[] = "Excerpt field override '<strong>{$field_name}</strong>' for '<strong>{$post_type_label}</strong>' does not exist on this site and was skipped."; 2837 } 2838 } else { 2839 $warnings[] = "Custom post type '<strong>{$post_type}</strong>' does not exist, so its excerpt field override was skipped."; 2840 } 2841 } 2842 update_option( $key, $valid_excerpt_overrides ); 2775 2843 continue; 2776 2844 } … … 2825 2893 exit; 2826 2894 } 2827 2828 } 2895 } // End Searchcraft_Admin -
searchcraft/trunk/admin/css/searchcraft-admin.css
r3429840 r3441163 354 354 select.searchcraft-select { 355 355 max-width: none; 356 } 357 358 /* Excerpt Override Custom Dropdown */ 359 .searchcraft-excerpt-select-wrapper { 360 position: relative; 361 display: inline-block; 362 max-width: 300px; 363 width: 100%; 364 } 365 366 .searchcraft-excerpt-override-input { 367 width: 100%; 368 padding-right: 35px; 369 box-sizing: border-box; 370 cursor: pointer; 371 } 372 373 .searchcraft-excerpt-override-input:not([readonly]) { 374 cursor: text; 375 } 376 377 .searchcraft-excerpt-toggle-btn, 378 .searchcraft-excerpt-clear-btn { 379 position: absolute; 380 right: 1px; 381 top: 1px; 382 bottom: 1px; 383 width: 32px; 384 height: calc(100% - 2px); 385 border: none; 386 background: var(--scwp-white); 387 cursor: pointer; 388 display: flex; 389 align-items: center; 390 justify-content: center; 391 padding: 0; 392 border-left: 1px solid var(--scwp-gray-10); 393 transition: background-color 0.2s ease; 394 } 395 396 .searchcraft-excerpt-toggle-btn:hover, 397 .searchcraft-excerpt-clear-btn:hover { 398 background: var(--scwp-gray-0); 399 } 400 401 .searchcraft-excerpt-toggle-btn .dashicons, 402 .searchcraft-excerpt-clear-btn .dashicons { 403 width: 18px; 404 height: 18px; 405 font-size: 18px; 406 color: var(--scwp-gray-50); 407 } 408 409 .searchcraft-excerpt-clear-btn .dashicons { 410 color: var(--scwp-gray-40); 411 } 412 413 .searchcraft-excerpt-clear-btn:hover .dashicons { 414 color: var(--scwp-red-50); 415 } 416 417 .searchcraft-excerpt-dropdown { 418 position: absolute; 419 top: 100%; 420 left: 0; 421 right: 0; 422 margin-top: 2px; 423 background: var(--scwp-white); 424 border: 1px solid var(--scwp-gray-10); 425 border-radius: 3px; 426 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); 427 z-index: 1000; 428 max-height: 80vh; 429 overflow-y: auto; 430 } 431 432 .searchcraft-excerpt-dropdown-list { 433 padding: 4px 0; 434 } 435 436 .searchcraft-excerpt-option { 437 padding: 8px 12px; 438 cursor: pointer; 439 transition: background-color 0.15s ease; 440 } 441 442 .searchcraft-excerpt-option:hover { 443 background: var(--scwp-blue-0); 444 } 445 446 .searchcraft-excerpt-option em { 447 color: var(--scwp-gray-40); 448 font-style: italic; 356 449 } 357 450 … … 1356 1449 } 1357 1450 1451 .searchcraft-field-search-wrapper { 1452 margin-bottom: 16px; 1453 } 1454 1455 .searchcraft-field-search { 1456 width: 100%; 1457 padding: 8px 12px; 1458 border: 1px solid #dcdcde; 1459 border-radius: 4px; 1460 font-size: 14px; 1461 line-height: 1.5; 1462 transition: border-color 0.2s; 1463 } 1464 1465 .searchcraft-field-search:focus { 1466 border-color: #2271b1; 1467 outline: none; 1468 box-shadow: 0 0 0 1px #2271b1; 1469 } 1470 1358 1471 .searchcraft-custom-fields-list { 1359 1472 border: 1px solid #dcdcde; … … 1364 1477 } 1365 1478 1479 .searchcraft-custom-fields-list label.searchcraft-field-hidden { 1480 display: none; 1481 } 1482 1483 .searchcraft-custom-fields-list .searchcraft-no-results { 1484 padding: 20px; 1485 text-align: center; 1486 color: #646970; 1487 font-style: italic; 1488 } 1489 1366 1490 .searchcraft-custom-fields-list label { 1367 1491 display: block; -
searchcraft/trunk/admin/js/searchcraft-admin.js
r3429840 r3441163 423 423 424 424 /** 425 * Initialize excerpt override custom dropdowns 426 */ 427 function initExcerptOverrideInputs() { 428 const wrappers = document.querySelectorAll('.searchcraft-excerpt-select-wrapper'); 429 430 wrappers.forEach((wrapper) => { 431 const input = wrapper.querySelector('.searchcraft-excerpt-override-input'); 432 const hiddenInput = wrapper.querySelector('.searchcraft-excerpt-override-value'); 433 const toggleBtn = wrapper.querySelector('.searchcraft-excerpt-toggle-btn'); 434 const clearBtn = wrapper.querySelector('.searchcraft-excerpt-clear-btn'); 435 const dropdown = wrapper.querySelector('.searchcraft-excerpt-dropdown'); 436 const options = wrapper.querySelectorAll('.searchcraft-excerpt-option'); 437 438 if (!input || !hiddenInput || !toggleBtn || !clearBtn || !dropdown) { 439 return; 440 } 441 442 // Store all options for filtering 443 const allOptions = Array.from(options); 444 445 // Update button visibility based on value 446 function updateButtons() { 447 const hasValue = hiddenInput.value.trim() !== ''; 448 toggleBtn.style.display = hasValue ? 'none' : 'flex'; 449 clearBtn.style.display = hasValue ? 'flex' : 'none'; 450 } 451 452 // Initialize button state 453 updateButtons(); 454 455 // Toggle dropdown 456 toggleBtn.addEventListener('click', (e) => { 457 e.stopPropagation(); 458 const isOpen = dropdown.style.display === 'block'; 459 460 // Close all other dropdowns 461 document.querySelectorAll('.searchcraft-excerpt-dropdown').forEach(d => { 462 d.style.display = 'none'; 463 }); 464 465 if (!isOpen) { 466 dropdown.style.display = 'block'; 467 input.removeAttribute('readonly'); 468 input.focus(); 469 // Show all options 470 allOptions.forEach(opt => opt.style.display = 'block'); 471 } 472 }); 473 474 // Clear selection 475 clearBtn.addEventListener('click', (e) => { 476 e.stopPropagation(); 477 input.value = ''; 478 hiddenInput.value = ''; 479 updateButtons(); 480 dropdown.style.display = 'none'; 481 }); 482 483 // Filter options as user types 484 input.addEventListener('input', () => { 485 const searchTerm = input.value.toLowerCase(); 486 let hasVisibleOptions = false; 487 488 allOptions.forEach((option) => { 489 const text = option.textContent.toLowerCase(); 490 const matches = text.includes(searchTerm); 491 option.style.display = matches ? 'block' : 'none'; 492 if (matches) hasVisibleOptions = true; 493 }); 494 495 // Show dropdown if typing and has results 496 if (searchTerm && hasVisibleOptions) { 497 dropdown.style.display = 'block'; 498 } 499 }); 500 501 // Select option 502 allOptions.forEach((option) => { 503 option.addEventListener('click', (e) => { 504 e.stopPropagation(); 505 const value = option.getAttribute('data-value'); 506 const text = value === '' ? '' : option.textContent.trim(); 507 508 input.value = text; 509 hiddenInput.value = value; 510 dropdown.style.display = 'none'; 511 input.setAttribute('readonly', 'readonly'); 512 updateButtons(); 513 }); 514 }); 515 516 // Close dropdown when clicking outside 517 document.addEventListener('click', (e) => { 518 if (!wrapper.contains(e.target)) { 519 dropdown.style.display = 'none'; 520 // Restore value if user was typing but didn't select 521 const currentValue = hiddenInput.value; 522 if (currentValue) { 523 const selectedOption = allOptions.find(opt => opt.getAttribute('data-value') === currentValue); 524 input.value = selectedOption ? selectedOption.textContent.trim() : ''; 525 } else { 526 input.value = ''; 527 } 528 input.setAttribute('readonly', 'readonly'); 529 } 530 }); 531 532 // Handle keyboard navigation 533 input.addEventListener('keydown', (e) => { 534 if (e.key === 'Escape') { 535 dropdown.style.display = 'none'; 536 input.setAttribute('readonly', 'readonly'); 537 } 538 }); 539 }); 540 } 541 542 /** 425 543 * Initialize drag and drop for filter panel items 426 544 */ … … 542 660 initCustomPostTypeCheckboxes(); 543 661 662 // Initialize excerpt override inputs with datalist 663 initExcerptOverrideInputs(); 664 544 665 // layout tab functionality 545 666 if (document.querySelector('.searchcraft-layout')) { … … 636 757 const modalTitle = document.getElementById('searchcraft-modal-title'); 637 758 const fieldsList = document.getElementById('searchcraft-custom-fields-list'); 759 const searchInput = document.getElementById('searchcraft-field-search'); 638 760 const selectAllBtn = modal.querySelector('.searchcraft-select-all-fields'); 639 761 const deselectAllBtn = modal.querySelector('.searchcraft-deselect-all-fields'); … … 714 836 } 715 837 838 // Clear search input 839 if (searchInput) { 840 searchInput.value = ''; 841 } 842 716 843 // Show modal 717 844 modal.style.display = 'block'; 718 845 document.body.style.overflow = 'hidden'; 846 847 // Focus search input 848 setTimeout(() => { 849 if (searchInput) { 850 searchInput.focus(); 851 } 852 }, 100); 719 853 } 720 854 … … 724 858 currentPostType = null; 725 859 currentButton = null; 860 } 861 862 function filterFields(searchTerm) { 863 const labels = fieldsList.querySelectorAll('label'); 864 const normalizedSearch = searchTerm.toLowerCase().trim(); 865 let visibleCount = 0; 866 867 labels.forEach((label) => { 868 const fieldName = label.textContent.trim().toLowerCase(); 869 const matches = fieldName.includes(normalizedSearch); 870 871 if (matches) { 872 label.classList.remove('searchcraft-field-hidden'); 873 visibleCount++; 874 } else { 875 label.classList.add('searchcraft-field-hidden'); 876 } 877 }); 878 879 // Show/hide "no results" message 880 let noResultsMsg = fieldsList.querySelector('.searchcraft-no-results'); 881 if (visibleCount === 0 && normalizedSearch !== '') { 882 if (!noResultsMsg) { 883 noResultsMsg = document.createElement('div'); 884 noResultsMsg.className = 'searchcraft-no-results'; 885 noResultsMsg.textContent = 'No fields found matching your search.'; 886 fieldsList.appendChild(noResultsMsg); 887 } 888 } else if (noResultsMsg) { 889 noResultsMsg.remove(); 890 } 726 891 } 727 892 … … 767 932 768 933 // Event listeners 934 searchInput?.addEventListener('input', (e) => { 935 filterFields(e.target.value); 936 }); 937 769 938 selectAllBtn?.addEventListener('click', () => { 770 const checkboxes = fieldsList.querySelectorAll('input[type="checkbox"] ');939 const checkboxes = fieldsList.querySelectorAll('input[type="checkbox"]:not(.searchcraft-field-hidden input)'); 771 940 checkboxes.forEach((checkbox) => { 772 checkbox.checked = true; 941 const label = checkbox.closest('label'); 942 if (!label || !label.classList.contains('searchcraft-field-hidden')) { 943 checkbox.checked = true; 944 } 773 945 }); 774 946 }); 775 947 776 948 deselectAllBtn?.addEventListener('click', () => { 777 const checkboxes = fieldsList.querySelectorAll('input[type="checkbox"] ');949 const checkboxes = fieldsList.querySelectorAll('input[type="checkbox"]:not(.searchcraft-field-hidden input)'); 778 950 checkboxes.forEach((checkbox) => { 779 checkbox.checked = false; 951 const label = checkbox.closest('label'); 952 if (!label || !label.classList.contains('searchcraft-field-hidden')) { 953 checkbox.checked = false; 954 } 780 955 }); 781 956 }); -
searchcraft/trunk/admin/partials/searchcraft-admin-config-tab.php
r3438759 r3441163 72 72 if ( ! is_array( $selected_custom_fields ) ) { 73 73 $selected_custom_fields = array(); 74 } 75 76 // Get excerpt field overrides for each post type. 77 $excerpt_field_overrides = get_option( 'searchcraft_excerpt_field_overrides', array() ); 78 if ( ! is_array( $excerpt_field_overrides ) ) { 79 $excerpt_field_overrides = array(); 74 80 } 75 81 … … 322 328 $selected_count = count( $post_type_selected_fields ); 323 329 $total_count = count( $meta_keys ); 330 $excerpt_override = isset( $excerpt_field_overrides[ $post_type_obj->name ] ) ? $excerpt_field_overrides[ $post_type_obj->name ] : ''; 324 331 ?> 325 332 <div style="margin-bottom: 12px;"> … … 361 368 <?php endif; ?> 362 369 </button> 370 </div> 371 <div class="searchcraft-excerpt-override-option" style="margin-top: 8px;"> 372 <label for="searchcraft_excerpt_override_<?php echo esc_attr( $post_type_obj->name ); ?>" style="display: block; margin-bottom: 4px; font-weight: normal;"> 373 Override excerpt field with custom field: 374 </label> 375 <?php 376 // Sort meta keys alphabetically for better UX. 377 $sorted_meta_keys = $meta_keys; 378 ksort( $sorted_meta_keys ); 379 ?> 380 <div class="searchcraft-excerpt-select-wrapper" data-post-type="<?php echo esc_attr( $post_type_obj->name ); ?>"> 381 <input 382 type="text" 383 id="searchcraft_excerpt_override_<?php echo esc_attr( $post_type_obj->name ); ?>" 384 class="searchcraft-excerpt-override-input" 385 value="<?php echo esc_attr( $excerpt_override ); ?>" 386 placeholder="Use default excerpt (or type to search)" 387 autocomplete="off" 388 readonly 389 /> 390 <input 391 type="hidden" 392 name="searchcraft_excerpt_field_overrides[<?php echo esc_attr( $post_type_obj->name ); ?>]" 393 class="searchcraft-excerpt-override-value" 394 value="<?php echo esc_attr( $excerpt_override ); ?>" 395 /> 396 <button type="button" class="searchcraft-excerpt-toggle-btn" aria-label="Toggle dropdown"> 397 <span class="dashicons dashicons-arrow-down-alt2"></span> 398 </button> 399 <button type="button" class="searchcraft-excerpt-clear-btn" aria-label="Clear selection" style="display: none;"> 400 <span class="dashicons dashicons-no-alt"></span> 401 </button> 402 <div class="searchcraft-excerpt-dropdown" style="display: none;"> 403 <div class="searchcraft-excerpt-dropdown-list"> 404 <div class="searchcraft-excerpt-option" data-value=""> 405 <em>Use default excerpt</em> 406 </div> 407 <?php foreach ( $sorted_meta_keys as $meta_key => $meta_info ) : ?> 408 <div class="searchcraft-excerpt-option" data-value="<?php echo esc_attr( $meta_key ); ?>"> 409 <?php echo esc_html( $meta_key ); ?> 410 </div> 411 <?php endforeach; ?> 412 </div> 413 </div> 414 </div> 415 <p class="description" style="margin-top: 4px;"> 416 Type to search or click the dropdown arrow to browse. Leave empty to use the default post excerpt. 417 </p> 363 418 </div> 364 419 </div> … … 475 530 <button type="button" class="button searchcraft-deselect-all-fields">Deselect All</button> 476 531 </div> 532 <div class="searchcraft-field-search-wrapper"> 533 <input 534 type="text" 535 id="searchcraft-field-search" 536 class="searchcraft-field-search" 537 placeholder="Search fields by name..." 538 autocomplete="off" 539 /> 540 </div> 477 541 <div id="searchcraft-custom-fields-list" class="searchcraft-custom-fields-list"> 478 542 <!-- Fields will be populated dynamically --> -
searchcraft/trunk/readme.txt
r3438759 r3441163 5 5 Requires at least: 5.3 6 6 Tested up to: 6.9 7 Stable tag: 1.3. 17 Stable tag: 1.3.2 8 8 License: Apache 2.0 9 9 License URI: LICENSE.txt … … 69 69 70 70 == Changelog == 71 72 = 1.3.2 = 73 * New Feature - Adds a search field to filter and locate custom fields in the configuration modal. 74 * New Feature - Add ability to override the excerpt shown in search results for custom types with a custom field value. 71 75 72 76 = 1.3.1 = -
searchcraft/trunk/searchcraft.php
r3438759 r3441163 11 11 * Plugin URI: https://github.com/searchcraft-inc/searchcraft-wordpress 12 12 * Description: Bring fast, relevant search to your site. Searchcraft replaces the default search with a customizable, tunable, highly relevant search experience. 13 * Version: 1.3. 113 * Version: 1.3.2 14 14 * Author: Searchcraft, Inc. 15 15 * Author URI: https://searchcraft.io/ … … 27 27 // Define plugin constants. 28 28 if ( ! defined( 'SEARCHCRAFT_VERSION' ) ) { 29 define( 'SEARCHCRAFT_VERSION', '1.3. 1' );29 define( 'SEARCHCRAFT_VERSION', '1.3.2' ); 30 30 } 31 31
Note: See TracChangeset
for help on using the changeset viewer.