Changeset 3392914
- Timestamp:
- 11/10/2025 11:51:05 AM (5 weeks ago)
- Location:
- naibabiji-b2b-product-showcase
- Files:
-
- 37 added
- 14 edited
-
tags/1.0.9 (added)
-
tags/1.0.9/assets (added)
-
tags/1.0.9/assets/css (added)
-
tags/1.0.9/assets/css/admin.css (added)
-
tags/1.0.9/assets/css/frontend.css (added)
-
tags/1.0.9/assets/js (added)
-
tags/1.0.9/assets/js/admin.js (added)
-
tags/1.0.9/assets/js/frontend.js (added)
-
tags/1.0.9/composer.json (added)
-
tags/1.0.9/includes (added)
-
tags/1.0.9/includes/class-admin-settings.php (added)
-
tags/1.0.9/includes/class-ajax-handlers.php (added)
-
tags/1.0.9/includes/class-frontend-display.php (added)
-
tags/1.0.9/includes/class-hooks.php (added)
-
tags/1.0.9/includes/class-meta-fields.php (added)
-
tags/1.0.9/includes/class-security.php (added)
-
tags/1.0.9/includes/class-shortcodes.php (added)
-
tags/1.0.9/includes/class-taxonomy-fields.php (added)
-
tags/1.0.9/includes/class-template-loader.php (added)
-
tags/1.0.9/includes/class-upgrader.php (added)
-
tags/1.0.9/includes/post-types.php (added)
-
tags/1.0.9/languages (added)
-
tags/1.0.9/languages/naibabiji-b2b-product-showcase-en_US.l10n.php (added)
-
tags/1.0.9/languages/naibabiji-b2b-product-showcase-en_US.mo (added)
-
tags/1.0.9/languages/naibabiji-b2b-product-showcase-en_US.po (added)
-
tags/1.0.9/languages/naibabiji-b2b-product-showcase-zh_CN.l10n.php (added)
-
tags/1.0.9/languages/naibabiji-b2b-product-showcase-zh_CN.mo (added)
-
tags/1.0.9/languages/naibabiji-b2b-product-showcase-zh_CN.po (added)
-
tags/1.0.9/languages/naibabiji-b2b-product-showcase.pot (added)
-
tags/1.0.9/naibabiji-b2b-product-showcase.php (added)
-
tags/1.0.9/readme.txt (added)
-
tags/1.0.9/templates (added)
-
tags/1.0.9/templates/archive-naibb2pr_products.php (added)
-
tags/1.0.9/templates/content-product-card.php (added)
-
tags/1.0.9/templates/single-naibb2pr_products.php (added)
-
tags/1.0.9/templates/taxonomy-naibb2pr_product_category.php (added)
-
tags/1.0.9/templates/taxonomy-naibb2pr_product_tag.php (added)
-
trunk/assets/js/admin.js (modified) (2 diffs)
-
trunk/includes/class-admin-settings.php (modified) (6 diffs)
-
trunk/includes/class-ajax-handlers.php (modified) (3 diffs)
-
trunk/includes/class-frontend-display.php (modified) (5 diffs)
-
trunk/includes/class-hooks.php (modified) (2 diffs)
-
trunk/includes/class-meta-fields.php (modified) (6 diffs)
-
trunk/includes/class-shortcodes.php (modified) (2 diffs)
-
trunk/naibabiji-b2b-product-showcase.php (modified) (7 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/templates/archive-naibb2pr_products.php (modified) (3 diffs)
-
trunk/templates/content-product-card.php (modified) (4 diffs)
-
trunk/templates/single-naibb2pr_products.php (modified) (3 diffs)
-
trunk/templates/taxonomy-naibb2pr_product_category.php (modified) (6 diffs)
-
trunk/templates/taxonomy-naibb2pr_product_tag.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
naibabiji-b2b-product-showcase/trunk/assets/js/admin.js
r3350010 r3392914 6 6 'use strict'; 7 7 8 var adminData = window.naibabiji_b2b_product_showcase_admin || {}; 9 var adminStrings = adminData.strings || {}; 10 8 11 /** 9 12 * Product Gallery Management … … 104 107 // Real-time preview of inquiry button text 105 108 $('#inquiry_button_text').on('input', function() { 106 var text = $(this).val() || 'Get Quote';109 var text = $(this).val() || adminStrings.default_inquiry_text || 'Get Quote'; 107 110 $('.inquiry-button-preview').text(text); 108 111 }); -
naibabiji-b2b-product-showcase/trunk/includes/class-admin-settings.php
r3351090 r3392914 47 47 public function register_settings() { 48 48 // Register settings group 49 // Appearance 50 register_setting('naibabiji_b2b_product_settings', 'naibabiji_b2b_product_button_color', array( 51 'type' => 'string', 52 'default' => '#0A7AFF', 53 'sanitize_callback' => array($this, 'sanitize_hex_color_strict') 54 )); 55 56 register_setting('naibabiji_b2b_product_settings', 'naibabiji_b2b_product_button_hover_color', array( 57 'type' => 'string', 58 'default' => '#085FCC', 59 'sanitize_callback' => array($this, 'sanitize_hex_color_strict') 60 )); 61 49 62 register_setting('naibabiji_b2b_product_settings', 'naibabiji_b2b_product_inquiry_button_text', array( 50 63 'type' => 'string', … … 78 91 79 92 // Add settings sections 93 94 add_settings_section( 95 'naibabiji_b2b_product_appearance_section', 96 __('Appearance Settings', 'naibabiji-b2b-product-showcase'), 97 array($this, 'appearance_section_callback'), 98 'naibabiji_b2b_product_settings' 99 ); 80 100 81 101 add_settings_section( … … 94 114 95 115 // Add settings fields 116 117 add_settings_field( 118 'button_color', 119 __('Primary Button Color', 'naibabiji-b2b-product-showcase'), 120 array($this, 'button_color_callback'), 121 'naibabiji_b2b_product_settings', 122 'naibabiji_b2b_product_appearance_section' 123 ); 124 125 add_settings_field( 126 'button_hover_color', 127 __('Button Hover Color', 'naibabiji-b2b-product-showcase'), 128 array($this, 'button_hover_color_callback'), 129 'naibabiji_b2b_product_settings', 130 'naibabiji_b2b_product_appearance_section' 131 ); 96 132 97 133 … … 148 184 <div class="wrap"> 149 185 <h1><?php echo esc_html__('Product Showcase Settings', 'naibabiji-b2b-product-showcase'); ?></h1> 186 <?php 187 // Enqueue color picker assets for this page 188 wp_enqueue_style('wp-color-picker'); 189 wp_enqueue_script('wp-color-picker'); 190 ?> 150 191 <form method="post" action="options.php"> 151 192 <?php … … 205 246 206 247 // 设置字段回调函数 207 248 public function appearance_section_callback() { 249 echo '<p>' . esc_html__('Customize colors for buttons on product listings and details.', 'naibabiji-b2b-product-showcase') . '</p>'; 250 } 251 252 public function button_color_callback() { 253 $value = get_option('naibabiji_b2b_product_button_color', '#0A7AFF'); 254 echo '<input type="text" name="naibabiji_b2b_product_button_color" value="' . esc_attr($value) . '" class="regular-text naibabiji-color-field" data-default-color="#0A7AFF" />'; 255 echo '<p class="description">' . esc_html__('Affects "View Details" and "Inquiry" buttons.', 'naibabiji-b2b-product-showcase') . '</p>'; 256 // Initialize color picker 257 echo '<script>jQuery(function($){$(".naibabiji-color-field").wpColorPicker();});</script>'; 258 } 259 260 public function button_hover_color_callback() { 261 $value = get_option('naibabiji_b2b_product_button_hover_color', '#085FCC'); 262 echo '<input type="text" name="naibabiji_b2b_product_button_hover_color" value="' . esc_attr($value) . '" class="regular-text naibabiji-color-field" data-default-color="#085FCC" />'; 263 } 264 208 265 public function inquiry_button_text_callback() { 209 266 $value = get_option('naibabiji_b2b_product_inquiry_button_text', __('Get Quote', 'naibabiji-b2b-product-showcase')); … … 234 291 echo '<p class="description">' . esc_html__('Number of words to show in product excerpts on archive and search pages', 'naibabiji-b2b-product-showcase') . '</p>'; 235 292 } 293 294 /** 295 * Strict HEX color sanitizer: returns default if invalid 296 */ 297 public function sanitize_hex_color_strict( $color ) { 298 $color = trim( (string) $color ); 299 // Allow 3 or 6 hex, with leading # 300 if ( preg_match( '/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/', $color ) ) { 301 return strtoupper($color); 302 } 303 return '#0A7AFF'; 304 } 236 305 } -
naibabiji-b2b-product-showcase/trunk/includes/class-ajax-handlers.php
r3350010 r3392914 161 161 } 162 162 163 // 获取默认设置 164 $default_options = array( 165 'naibabiji_b2b_thumbnail_width' => 300, 166 'naibabiji_b2b_thumbnail_height' => 300, 167 'naibabiji_b2b_posts_per_page' => 12, 168 'naibabiji_b2b_inquiry_button_text' => __('Get Quote', 'naibabiji-b2b-product-showcase'), 169 'naibabiji_b2b_default_inquiry_link' => '', 170 'naibabiji_b2b_enable_breadcrumbs' => 1, 171 'naibabiji_b2b_enable_schema' => 1, 172 ); 163 // 获取默认设置(与已注册的设置键名保持一致) 164 $default_options = array( 165 'naibabiji_b2b_product_products_per_page' => 12, 166 'naibabiji_b2b_product_inquiry_button_text' => __('Get Quote', 'naibabiji-b2b-product-showcase'), 167 'naibabiji_b2b_product_default_inquiry_url' => '', 168 'naibabiji_b2b_product_enable_breadcrumbs' => 1, 169 'naibabiji_b2b_product_enable_schema' => 1, 170 'naibabiji_b2b_product_excerpt_length' => 20, 171 'naibabiji_b2b_product_button_color' => '#0A7AFF', 172 'naibabiji_b2b_product_button_hover_color' => '#085FCC', 173 ); 173 174 174 175 // 重置所有设置 … … 268 269 $query->the_post(); 269 270 270 // 使用模板部分而不是调用不存在的方法271 ob_start();272 include NAIBABIJI_B2B_PRODUCT_SHOWCASE_PLUGIN_PATH. 'templates/content-product-card.php';273 $html .= ob_get_clean();271 // 使用模板部分而不是调用不存在的方法 272 ob_start(); 273 include NAIBABIJI_B2B_PRODUCT_SHOWCASE_PLUGIN_DIR . 'templates/content-product-card.php'; 274 $html .= ob_get_clean(); 274 275 } 275 276 … … 352 353 $query->the_post(); 353 354 354 // 使用模板部分而不是调用不存在的方法355 ob_start();356 include NAIBABIJI_B2B_PRODUCT_SHOWCASE_PLUGIN_PATH. 'templates/content-product-card.php';357 $html .= ob_get_clean();355 // 使用模板部分而不是调用不存在的方法 356 ob_start(); 357 include NAIBABIJI_B2B_PRODUCT_SHOWCASE_PLUGIN_DIR . 'templates/content-product-card.php'; 358 $html .= ob_get_clean(); 358 359 } 359 360 -
naibabiji-b2b-product-showcase/trunk/includes/class-frontend-display.php
r3350010 r3392914 125 125 $output .= '<div class="naibabiji-b2b-product-excerpt">'; 126 126 $output .= '<h3>' . esc_html__( 'Product Introduction', 'naibabiji-b2b-product-showcase' ) . '</h3>'; 127 $output .= '<p>' . get_the_excerpt( $post ) . '</p>'; 127 // 使用post_excerpt原文并保留格式,限制为安全的HTML标签 128 $raw_excerpt = get_post_field( 'post_excerpt', $post ); 129 $output .= wpautop( wp_kses_post( $raw_excerpt ) ); 128 130 $output .= '</div>'; 129 131 } … … 275 277 276 278 // 首页 277 $breadcrumbs[] = '<a href="' . home_url('/') . '">' . esc_html__('Home', 'naibabiji-b2b-product-showcase') . '</a>';279 $breadcrumbs[] = '<a href="' . esc_url(home_url('/')) . '">' . esc_html__('Home', 'naibabiji-b2b-product-showcase') . '</a>'; 278 280 279 281 // 产品归档页 280 $breadcrumbs[] = '<a href="' . get_post_type_archive_link('naibb2pr_products') . '">' . esc_html__('Products', 'naibabiji-b2b-product-showcase') . '</a>';282 $breadcrumbs[] = '<a href="' . esc_url(get_post_type_archive_link('naibb2pr_products')) . '">' . esc_html__('Products', 'naibabiji-b2b-product-showcase') . '</a>'; 281 283 282 284 // 产品分类 … … 284 286 if ($categories && !is_wp_error($categories)) { 285 287 $category = $categories[0]; 286 $breadcrumbs[] = '<a href="' . get_term_link($category) . '">' . $category->name . '</a>'; 288 $category_link = get_term_link($category); 289 if (!is_wp_error($category_link)) { 290 $breadcrumbs[] = '<a href="' . esc_url($category_link) . '">' . esc_html($category->name) . '</a>'; 291 } 287 292 } 288 293 289 294 // 当前产品 290 $breadcrumbs[] = '<span class="current">' . get_the_title($post) . '</span>';295 $breadcrumbs[] = '<span class="current">' . esc_html(get_the_title($post)) . '</span>'; 291 296 292 297 echo '<nav class="naibabiji-b2b-breadcrumbs" aria-label="' . esc_attr__('Breadcrumb Navigation', 'naibabiji-b2b-product-showcase') . '">'; … … 336 341 $output = '<div class="naibabiji-b2b-products-grid naibabiji-b2b-columns-' . esc_attr($args['columns']) . '">'; 337 342 343 // 通过模板渲染产品卡片,避免重复HTML实现 344 $naibabiji_b2b_show_excerpt = (bool) $args['show_excerpt']; 338 345 while ($products->have_posts()) { 339 346 $products->the_post(); 340 $output .= self::get_product_card_html($args); 347 ob_start(); 348 include NAIBABIJI_B2B_PRODUCT_SHOWCASE_PLUGIN_DIR . 'templates/content-product-card.php'; 349 $output .= ob_get_clean(); 341 350 } 342 351 … … 352 361 */ 353 362 private static function get_product_card_html($args) { 354 $post_id = get_the_ID(); 355 356 $output = '<div class="naibabiji-b2b-product-card">'; 357 358 // 产品缩略图 359 if (has_post_thumbnail()) { 360 $output .= '<div class="naibabiji-b2b-product-thumbnail">'; 361 $output .= '<a href="' . get_permalink() . '">'; 362 $output .= get_the_post_thumbnail($post_id, 'medium'); 363 $output .= '</a>'; 364 $output .= '</div>'; 365 } 366 367 $output .= '<div class="naibabiji-b2b-product-info">'; 368 369 // 产品标题 370 $output .= '<h3 class="naibabiji-b2b-product-title">'; 371 $output .= '<a href="' . get_permalink() . '">' . get_the_title() . '</a>'; 372 $output .= '</h3>'; 373 374 // 产品简短描述 375 if ($args['show_excerpt'] && has_excerpt()) { 376 $output .= '<div class="naibabiji-b2b-product-excerpt">'; 377 $output .= '<p>' . get_the_excerpt() . '</p>'; 378 $output .= '</div>'; 379 } 380 381 // 按钮区域 - 只显示查看详情按钮 382 $output .= '<div class="naibabiji-b2b-product-actions">'; 383 $output .= '<div class="naibabiji-b2b-button-group">'; 384 385 // 查看详情按钮(与产品列表页保持一致) 386 $output .= '<a href="' . get_permalink() . '" class="naibabiji-b2b-view-details-button">'; 387 $output .= '<span class="naibabiji-b2b-button-icon">→</span>' . __('View Details', 'naibabiji-b2b-product-showcase'); 388 $output .= '</a>'; 389 390 $output .= '</div>'; // .naibabiji-b2b-button-group 391 $output .= '</div>'; // .naibabiji-b2b-product-actions 392 393 $output .= '</div>'; // .naibabiji-b2b-product-info 394 $output .= '</div>'; // .naibabiji-b2b-product-card 395 396 return $output; 363 // 已由模板渲染,不再使用此实现;保留方法以兼容潜在外部调用 364 ob_start(); 365 include NAIBABIJI_B2B_PRODUCT_SHOWCASE_PLUGIN_DIR . 'templates/content-product-card.php'; 366 return ob_get_clean(); 397 367 } 398 368 } -
naibabiji-b2b-product-showcase/trunk/includes/class-hooks.php
r3350010 r3392914 170 170 public function settings_saved($settings) { 171 171 // 清除相关缓存 172 $this->clear_plugin_cache( );172 $this->clear_plugin_cache($settings); 173 173 174 174 /** … … 228 228 * 清除插件缓存 229 229 */ 230 private function clear_plugin_cache() { 231 // 清除WordPress对象缓存 232 wp_cache_flush(); 233 234 // 清除重写规则缓存 235 flush_rewrite_rules(); 236 237 // 如果使用了第三方缓存插件,可以在这里添加清除逻辑 238 if (function_exists('wp_cache_clear_cache')) { 239 wp_cache_clear_cache(); 240 } 241 242 if (function_exists('w3tc_flush_all')) { 243 w3tc_flush_all(); 244 } 245 246 if (function_exists('wp_rocket_clean_domain')) { 247 wp_rocket_clean_domain(); 248 } 230 private function clear_plugin_cache($settings) { 231 $should_flush_object_cache = apply_filters('naibabiji_b2b_flush_object_cache', false, $settings); 232 if ($should_flush_object_cache && function_exists('wp_cache_flush')) { 233 wp_cache_flush(); 234 } 235 236 $should_flush_rewrite = apply_filters('naibabiji_b2b_flush_rewrite_rules', false, $settings); 237 if ($should_flush_rewrite) { 238 flush_rewrite_rules(false); 239 } 240 241 /** 242 * Allow third-party integrations to clear their caches when settings are saved. 243 * 244 * @since 1.1.0 245 * @param array $settings Saved settings. 246 */ 247 do_action('naibabiji_b2b_clear_external_cache', $settings); 249 248 } 250 249 -
naibabiji-b2b-product-showcase/trunk/includes/class-meta-fields.php
r3351090 r3392914 52 52 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) ); 53 53 add_action( 'admin_head', array( $this, 'force_show_excerpt_box' ) ); 54 add_filter( 'default_hidden_meta_boxes', array( $this, 'show_short_description_meta_box' ), 10, 2 ); 54 55 55 56 // Add excerpt support immediately, rather than through the init hook … … 66 67 public function add_meta_boxes() { 67 68 add_meta_box( 68 'naibabiji_b2b_product_short_description ',69 'naibabiji_b2b_product_short_description_box', 69 70 esc_html__( 'Product Short Description', 'naibabiji-b2b-product-showcase' ), 70 71 array( $this, 'render_short_description_meta_box' ), … … 123 124 } 124 125 ?> 125 <table class="form-table ">126 <table class="form-table naibabiji-b2b-short-desc-wrapper"> 126 127 <tr> 127 128 <td> 128 129 <label for="naibabiji_b2b_product_short_description"><?php esc_html_e( 'Product Short Description:', 'naibabiji-b2b-product-showcase' ); ?></label> 129 <textarea id="naibabiji_b2b_product_short_description" name="naibabiji_b2b_product_short_description" 130 rows="4" class="widefat" 131 placeholder="<?php esc_attr_e( 'Enter a short description of the product, which will be displayed in the product list and detail page...', 'naibabiji-b2b-product-showcase' ); ?>"><?php echo esc_textarea( $short_description ); ?></textarea> 130 <?php 131 // 确保保存时有可用的nonce 132 wp_nonce_field( 'naibabiji_b2b_product_meta_nonce', 'naibabiji_b2b_product_meta_nonce' ); 133 ?> 134 <div class="naibabiji-b2b-short-desc-editor"> 135 <?php 136 // 使用TinyMCE富文本编辑器 137 wp_editor( 138 $short_description, 139 'naibabiji_b2b_product_short_description', 140 array( 141 'textarea_name' => 'naibabiji_b2b_product_short_description', 142 'textarea_rows' => 10, 143 'editor_height' => 220, 144 'media_buttons' => false, 145 'teeny' => false, 146 'drag_drop_upload' => false, 147 'quicktags' => array( 148 'buttons' => 'strong,em,del,ul,ol,li,link' 149 ), 150 'tinymce' => array( 151 'toolbar1' => 'bold,italic,underline,forecolor,bullist,numlist,link,unlink,removeformat', 152 'toolbar2' => '', 153 'statusbar' => false, 154 'branding' => false, 155 ), 156 ) 157 ); 158 ?> 159 </div> 132 160 <p class="description"><?php esc_html_e( 'Short description is used for display in product listing pages and search results, recommended to keep within 100-200 characters.', 'naibabiji-b2b-product-showcase' ); ?></p> 133 161 </td> … … 294 322 // 保存产品简短描述 295 323 if ( isset( $_POST['naibabiji_b2b_product_short_description'] ) ) { 296 $short_description = sanitize_textarea_field( wp_unslash( $_POST['naibabiji_b2b_product_short_description'] ) ); 324 // 允许安全的HTML以保留富文本格式 325 $short_description = wp_kses_post( wp_unslash( $_POST['naibabiji_b2b_product_short_description'] ) ); 297 326 update_post_meta( $post_id, '_naibabiji_b2b_product_short_description', $short_description ); 298 327 … … 343 372 global $post_type; 344 373 if ( 'naibb2pr_products' === $post_type ) { 374 if ( function_exists( 'wp_enqueue_editor' ) ) { 375 wp_enqueue_editor(); 376 } 345 377 wp_enqueue_media(); 346 378 wp_enqueue_script( 'jquery-ui-sortable' ); 347 379 } 348 380 } 381 } 382 /** 383 * 确保产品简介元框默认显示 384 * 385 * @since 1.0.0 386 * @param array $hidden 默认隐藏的元框ID数组 387 * @param WP_Screen $screen 当前屏幕对象 388 * @return array 389 */ 390 public function show_short_description_meta_box( $hidden, $screen ) { 391 if ( isset( $screen->post_type ) && 'naibb2pr_products' === $screen->post_type ) { 392 $index = array_search( 'naibabiji_b2b_product_short_description_box', $hidden, true ); 393 if ( false !== $index ) { 394 unset( $hidden[ $index ] ); 395 } 396 } 397 return $hidden; 349 398 } 350 399 … … 360 409 wp_add_inline_style( 361 410 'naibabiji-b2b-product-showcase-admin-style', 362 ' #naibabiji-b2b-product-short-description .form-tabletd {411 '.naibabiji-b2b-short-desc-wrapper td { 363 412 padding: 15px 0; 364 413 } 365 #naibabiji_b2b_product_short_description { 414 .naibabiji-b2b-short-desc-editor .wp-editor-wrap { 415 max-width: 100%; 416 } 417 .naibabiji-b2b-short-desc-editor .wp-editor-area { 366 418 width: 100%; 367 min-height: 80px;368 419 }' 369 420 ); -
naibabiji-b2b-product-showcase/trunk/includes/class-shortcodes.php
r3350010 r3392914 137 137 $thumbnail_id = get_term_meta($category->term_id, 'thumbnail_id', true); 138 138 if ($thumbnail_id) { 139 $term_link = get_term_link($category); 140 if (is_wp_error($term_link)) { 141 $term_link = ''; 142 } 139 143 $output .= '<div class="naibabiji-b2b-category-thumbnail">'; 140 $output .= '<a href="' . get_term_link($category) . '">'; 144 if ($term_link) { 145 $output .= '<a href="' . esc_url($term_link) . '">'; 146 } 141 147 $output .= wp_get_attachment_image($thumbnail_id, 'medium'); 142 $output .= '</a>'; 148 if ($term_link) { 149 $output .= '</a>'; 150 } 143 151 $output .= '</div>'; 144 152 } … … 148 156 // 分类名称 149 157 $output .= '<h3 class="naibabiji-b2b-category-title">'; 150 $output .= '<a href="' . get_term_link($category) . '">' . esc_html($category->name) . '</a>'; 158 $term_link = isset($term_link) ? $term_link : get_term_link($category); 159 if (!is_wp_error($term_link) && $term_link) { 160 $output .= '<a href="' . esc_url($term_link) . '">' . esc_html($category->name) . '</a>'; 161 } else { 162 $output .= esc_html($category->name); 163 } 151 164 $output .= '</h3>'; 152 165 -
naibabiji-b2b-product-showcase/trunk/naibabiji-b2b-product-showcase.php
r3381006 r3392914 4 4 * Plugin URI: https://blog.naibabiji.com 5 5 * Description: Lightweight B2B product showcase plugin designed for corporate websites, without shopping cart functionality, focusing on product display and inquiry. 6 * Version: 1.0. 86 * Version: 1.0.9 7 7 * Author: Naibabiji 8 8 * Text Domain: naibabiji-b2b-product-showcase … … 25 25 * 定义插件常量 26 26 */ 27 define( 'NAIBABIJI_B2B_PRODUCT_SHOWCASE_VERSION', '1.0. 8' );27 define( 'NAIBABIJI_B2B_PRODUCT_SHOWCASE_VERSION', '1.0.9' ); 28 28 define( 'NAIBABIJI_B2B_PRODUCT_SHOWCASE_AUTHOR', 'Naibabiji' ); 29 29 define( 'NAIBABIJI_B2B_PRODUCT_SHOWCASE_URI', 'https://blog.naibabiji.com' ); … … 207 207 */ 208 208 public function enqueue_scripts() { 209 if ( ! $this->should_enqueue_frontend_assets() ) { 210 return; 211 } 212 209 213 // Check if forced reload is needed 210 214 $force_reload = get_option( 'naibabiji_b2b_product_force_reload', false ); … … 217 221 $version 218 222 ); 223 224 // Inline dynamic styles for configurable button colors 225 $btn_color = get_option('naibabiji_b2b_product_button_color', '#0A7AFF'); 226 $btn_hover = get_option('naibabiji_b2b_product_button_hover_color', '#085FCC'); 227 $dynamic_css = " 228 .naibabiji-b2b-view-details-button, 229 .naibabiji-b2b-inquiry-button { 230 background-color: {$btn_color}; 231 border-color: {$btn_color}; 232 } 233 .naibabiji-b2b-view-details-button:hover, 234 .naibabiji-b2b-inquiry-button:hover, 235 .naibabiji-b2b-view-details-button:focus, 236 .naibabiji-b2b-inquiry-button:focus { 237 background-color: {$btn_hover}; 238 border-color: {$btn_hover}; 239 }"; 240 wp_add_inline_style('naibabiji-b2b-product-showcase-style', $dynamic_css); 219 241 220 242 wp_enqueue_script( … … 240 262 delete_option( 'naibabiji_b2b_product_force_reload' ); 241 263 } 264 } 265 266 /** 267 * Determine whether frontend assets should be loaded. 268 * 269 * @since 1.1.0 270 * @return bool 271 */ 272 private function should_enqueue_frontend_assets() { 273 if ( is_admin() ) { 274 return false; 275 } 276 277 if ( 278 is_singular( 'naibb2pr_products' ) || 279 is_post_type_archive( 'naibb2pr_products' ) || 280 is_tax( array( 'naibb2pr_product_category', 'naibb2pr_product_tag' ) ) 281 ) { 282 return true; 283 } 284 285 if ( is_singular() ) { 286 $post = get_post(); 287 if ( $post ) { 288 $content = $post->post_content; 289 if ( has_shortcode( $content, 'naibabiji_b2b_products' ) || has_shortcode( $content, 'naibabiji_b2b_product_categories' ) ) { 290 return true; 291 } 292 293 if ( function_exists( 'has_block' ) && ( 294 has_block( 'naibabiji-b2b/product-grid', $post ) || 295 has_block( 'naibabiji-b2b/category-grid', $post ) 296 ) ) { 297 return true; 298 } 299 } 300 } 301 302 /** 303 * Filters whether the frontend assets should be enqueued. 304 * 305 * @since 1.1.0 306 * @param bool $enqueue Whether to enqueue assets. Default false. 307 */ 308 return (bool) apply_filters( 'naibabiji_b2b_should_enqueue_frontend_assets', false ); 242 309 } 243 310 … … 277 344 'strings' => array( 278 345 'confirm_delete' => __( 'Are you sure you want to delete this item?', 'naibabiji-b2b-product-showcase' ), 346 'default_inquiry_text' => __( 'Get Quote', 'naibabiji-b2b-product-showcase' ), 279 347 ), 280 348 ) … … 339 407 // Initialize plugin 340 408 naibabiji_b2b_product_showcase(); 409 410 /** 411 * 在插件列表行元信息中添加“帮助”链接 412 * 413 * @param string[] $links 现有链接 414 * @param string $file 插件基名 415 * @return string[] 416 */ 417 add_filter( 'plugin_row_meta', 'naibabiji_b2b_product_row_meta', 10, 2 ); 418 function naibabiji_b2b_product_row_meta( $links, $file ) { 419 if ( $file === NAIBABIJI_B2B_PRODUCT_SHOWCASE_PLUGIN_BASENAME ) { 420 $links[] = '<a href="https://blog.naibabiji.com/files/wordpress-plugins/naibabiji-b2b-product-showcase.html" target="_blank" rel="noopener noreferrer">' . __( '帮助Help', 'naibabiji-b2b-product-showcase' ) . '</a>'; 421 } 422 return $links; 423 } -
naibabiji-b2b-product-showcase/trunk/readme.txt
r3381006 r3392914 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.4 7 Stable tag: 1.0. 87 Stable tag: 1.0.9 8 8 License: GPL v2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 80 80 For detailed parameters, please check the usage instructions on the settings page. 81 81 82 == Changelog == 82 = 1.0.9 = 83 * Added button color customization entry for front and back, managers can quickly adjust styles to match brand vision 84 * Replace the product short description with the fill-in area, use a rich text editor to optimize the input experience and improve Gutenberg compatibility 83 85 84 86 = 1.0.8 = -
naibabiji-b2b-product-showcase/trunk/templates/archive-naibb2pr_products.php
r3350010 r3392914 27 27 <?php if (is_tax() && term_description()) : ?> 28 28 <div class="naibabiji-b2b-archive-description"> 29 <?php echo term_description(); ?>29 <?php echo wp_kses_post(term_description()); ?> 30 30 </div> 31 31 <?php endif; ?> … … 50 50 </a> 51 51 <?php foreach ($categories as $category) : ?> 52 <a href="<?php echo esc_url(get_term_link($category)); ?>" 52 <?php 53 $category_link = get_term_link($category); 54 if (is_wp_error($category_link)) { 55 continue; 56 } 57 ?> 58 <a href="<?php echo esc_url($category_link); ?>" 53 59 class="filter-link <?php echo is_tax('naibb2pr_product_category', $category->slug) ? 'active' : ''; ?>"> 54 60 <?php echo esc_html($category->name); ?> … … 112 118 $product_categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category'); 113 119 if ($product_categories && !is_wp_error($product_categories)) : 120 $primary_category = $product_categories[0]; 121 $primary_category_link = get_term_link($primary_category, 'naibb2pr_product_category'); 122 if (!is_wp_error($primary_category_link)) : 114 123 ?> 115 124 <div class="naibabiji-b2b-product-meta"> 116 125 <span class="naibabiji-b2b-product-category"> 117 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?><a href="<?php echo esc_url(get_term_link($product_categories[0]->term_id, 'naibb2pr_product_category')); ?>"><?php echo esc_html($product_categories[0]->name); ?></a> 126 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?> 127 <a href="<?php echo esc_url($primary_category_link); ?>"> 128 <?php echo esc_html($primary_category->name); ?> 129 </a> 118 130 </span> 119 131 </div> 120 <?php endif; ?> 132 <?php 133 endif; 134 endif; 135 ?> 121 136 122 137 <div class="naibabiji-b2b-product-actions"> -
naibabiji-b2b-product-showcase/trunk/templates/content-product-card.php
r3350010 r3392914 11 11 12 12 $product_id = get_the_ID(); 13 $show_excerpt = isset($naibabiji_b2b_show_excerpt) ? (bool) $naibabiji_b2b_show_excerpt : true; 13 14 ?> 14 15 … … 27 28 </h2> 28 29 29 <?php if ( has_excerpt()) : ?>30 <?php if ($show_excerpt && has_excerpt()) : ?> 30 31 <div class="naibabiji-b2b-product-excerpt"> 31 32 <?php … … 41 42 $product_categories = get_the_terms($product_id, 'naibb2pr_product_category'); 42 43 if ($product_categories && !is_wp_error($product_categories)) : 44 $primary_category = $product_categories[0]; 45 $primary_category_link = get_term_link($primary_category, 'naibb2pr_product_category'); 46 if (!is_wp_error($primary_category_link)) : 43 47 ?> 44 48 <div class="naibabiji-b2b-product-meta"> 45 49 <span class="naibabiji-b2b-product-category"> 46 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?><a href="<?php echo esc_url(get_term_link($product_categories[0]->term_id, 'naibb2pr_product_category')); ?>"><?php echo esc_html($product_categories[0]->name); ?></a> 50 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?> 51 <a href="<?php echo esc_url($primary_category_link); ?>"> 52 <?php echo esc_html($primary_category->name); ?> 53 </a> 47 54 </span> 48 55 </div> 49 <?php endif; ?> 56 <?php 57 endif; 58 endif; 59 ?> 50 60 51 61 <div class="naibabiji-b2b-product-actions"> … … 59 69 $enable_inquiry = get_option('naibabiji_b2b_product_enable_inquiry_button', 1); 60 70 if ($enable_inquiry) : 61 $inquiry_text = get_post_meta($product_id, '_naibabiji_b2b_ inquiry_button_text', true);71 $inquiry_text = get_post_meta($product_id, '_naibabiji_b2b_product_inquiry_text', true); 62 72 if (empty($inquiry_text)) { 63 $inquiry_text = get_option('naibabiji_b2b_product_inquiry_button_text', 'Get Quote');73 $inquiry_text = get_option('naibabiji_b2b_product_inquiry_button_text', __('Get Quote', 'naibabiji-b2b-product-showcase')); 64 74 } 65 75 66 $inquiry_url = get_post_meta($product_id, '_naibabiji_b2b_ inquiry_url', true);76 $inquiry_url = get_post_meta($product_id, '_naibabiji_b2b_product_inquiry_url', true); 67 77 if (empty($inquiry_url)) { 68 78 $inquiry_url = get_option('naibabiji_b2b_product_default_inquiry_url', '#'); -
naibabiji-b2b-product-showcase/trunk/templates/single-naibb2pr_products.php
r3350010 r3392914 89 89 $category_links = array(); 90 90 foreach ($categories as $category) { 91 $category_links[] = '<a href="' . get_term_link($category) . '">' . $category->name . '</a>'; 91 $category_link = get_term_link($category); 92 if (!is_wp_error($category_link)) { 93 $category_links[] = '<a href="' . esc_url($category_link) . '">' . esc_html($category->name) . '</a>'; 94 } 92 95 } 93 96 echo wp_kses_post(implode(', ', $category_links)); … … 101 104 $tag_links = array(); 102 105 foreach ($tags as $tag) { 103 $tag_links[] = '<a href="' . get_term_link($tag) . '">' . $tag->name . '</a>'; 106 $tag_link = get_term_link($tag); 107 if (!is_wp_error($tag_link)) { 108 $tag_links[] = '<a href="' . esc_url($tag_link) . '">' . esc_html($tag->name) . '</a>'; 109 } 104 110 } 105 111 echo wp_kses_post(implode(', ', $tag_links)); … … 120 126 121 127 if (empty($inquiry_text)) { 122 $inquiry_text = get_option('naibabiji_b2b_product_inquiry_button_text', 'Get Quote');128 $inquiry_text = get_option('naibabiji_b2b_product_inquiry_button_text', __('Get Quote', 'naibabiji-b2b-product-showcase')); 123 129 } 124 130 -
naibabiji-b2b-product-showcase/trunk/templates/taxonomy-naibb2pr_product_category.php
r3350010 r3392914 19 19 <?php if (term_description()) : ?> 20 20 <div class="naibabiji-b2b-taxonomy-description"> 21 <?php echo term_description(); ?>21 <?php echo wp_kses_post(term_description()); ?> 22 22 </div> 23 23 <?php endif; ?> … … 35 35 $breadcrumbs = array(); 36 36 37 $breadcrumbs[] = '<a href="' . home_url('/') . '">' . esc_html__('Home', 'naibabiji-b2b-product-showcase') . '</a>';38 $breadcrumbs[] = '<a href="' . get_post_type_archive_link('naibb2pr_products') . '">' . esc_html__('Products', 'naibabiji-b2b-product-showcase') . '</a>';37 $breadcrumbs[] = '<a href="' . esc_url(home_url('/')) . '">' . esc_html__('Home', 'naibabiji-b2b-product-showcase') . '</a>'; 38 $breadcrumbs[] = '<a href="' . esc_url(get_post_type_archive_link('naibb2pr_products')) . '">' . esc_html__('Products', 'naibabiji-b2b-product-showcase') . '</a>'; 39 39 40 40 // If there are parent categories, add them to breadcrumbs … … 45 45 while ($parent_id) { 46 46 $parent = get_term($parent_id, 'naibb2pr_product_category'); 47 $parent_terms[] = '<a href="' . get_term_link($parent) . '">' . $parent->name . '</a>'; 47 if (is_wp_error($parent)) { 48 break; 49 } 50 51 $parent_link = get_term_link($parent); 52 if (is_wp_error($parent_link)) { 53 break; 54 } 55 56 $parent_terms[] = '<a href="' . esc_url($parent_link) . '">' . esc_html($parent->name) . '</a>'; 48 57 $parent_id = $parent->parent; 49 58 } … … 52 61 } 53 62 54 $breadcrumbs[] = '<span class="current">' . $current_term->name. '</span>';63 $breadcrumbs[] = '<span class="current">' . esc_html($current_term->name) . '</span>'; 55 64 ?> 56 65 … … 80 89 <ul class="naibabiji-b2b-category-list"> 81 90 <?php foreach ($child_terms as $child_term) : ?> 91 <?php 92 $child_link = get_term_link($child_term); 93 if (is_wp_error($child_link)) { 94 continue; 95 } 96 ?> 82 97 <li> 83 <a href="<?php echo esc_url( get_term_link($child_term)); ?>" class="naibabiji-b2b-category-link">98 <a href="<?php echo esc_url($child_link); ?>" class="naibabiji-b2b-category-link"> 84 99 <?php echo esc_html($child_term->name); ?> 85 100 </a> … … 121 136 $product_categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category'); 122 137 if ($product_categories && !is_wp_error($product_categories)) : 138 $primary_category = $product_categories[0]; 139 $primary_category_link = get_term_link($primary_category, 'naibb2pr_product_category'); 140 if (!is_wp_error($primary_category_link)) : 123 141 ?> 124 142 <div class="naibabiji-b2b-product-meta"> 125 143 <span class="naibabiji-b2b-product-category"> 126 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?><a href="<?php echo esc_url(get_term_link($product_categories[0]->term_id, 'naibb2pr_product_category')); ?>"><?php echo esc_html($product_categories[0]->name); ?></a> 144 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?> 145 <a href="<?php echo esc_url($primary_category_link); ?>"> 146 <?php echo esc_html($primary_category->name); ?> 147 </a> 127 148 </span> 128 149 </div> 129 <?php endif; ?> 150 <?php 151 endif; 152 endif; 153 ?> 130 154 131 155 <div class="naibabiji-b2b-product-actions"> -
naibabiji-b2b-product-showcase/trunk/templates/taxonomy-naibb2pr_product_tag.php
r3350010 r3392914 19 19 <?php if (term_description()) : ?> 20 20 <div class="naibabiji-b2b-taxonomy-description"> 21 <?php echo term_description(); ?>21 <?php echo wp_kses_post(term_description()); ?> 22 22 </div> 23 23 <?php endif; ?> … … 35 35 $breadcrumbs = array(); 36 36 37 $breadcrumbs[] = '<a href="' . home_url('/') . '">' . esc_html__('Home', 'naibabiji-b2b-product-showcase') . '</a>';38 $breadcrumbs[] = '<a href="' . get_post_type_archive_link('naibb2pr_products') . '">' . esc_html__('Products', 'naibabiji-b2b-product-showcase') . '</a>';39 $breadcrumbs[] = '<span class="current">' . $current_term->name. '</span>';37 $breadcrumbs[] = '<a href="' . esc_url(home_url('/')) . '">' . esc_html__('Home', 'naibabiji-b2b-product-showcase') . '</a>'; 38 $breadcrumbs[] = '<a href="' . esc_url(get_post_type_archive_link('naibb2pr_products')) . '">' . esc_html__('Products', 'naibabiji-b2b-product-showcase') . '</a>'; 39 $breadcrumbs[] = '<span class="current">' . esc_html($current_term->name) . '</span>'; 40 40 ?> 41 41 … … 82 82 $product_categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category'); 83 83 if ($product_categories && !is_wp_error($product_categories)) : 84 $primary_category = $product_categories[0]; 85 $primary_category_link = get_term_link($primary_category, 'naibb2pr_product_category'); 86 if (!is_wp_error($primary_category_link)) : 84 87 ?> 85 88 <div class="naibabiji-b2b-product-meta"> 86 89 <span class="naibabiji-b2b-product-category"> 87 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?><a href="<?php echo esc_url(get_term_link($product_categories[0]->term_id, 'naibb2pr_product_category')); ?>"><?php echo esc_html($product_categories[0]->name); ?></a> 90 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?> 91 <a href="<?php echo esc_url($primary_category_link); ?>"> 92 <?php echo esc_html($primary_category->name); ?> 93 </a> 88 94 </span> 89 95 </div> 90 <?php endif; ?> 96 <?php 97 endif; 98 endif; 99 ?> 91 100 92 101 <div class="naibabiji-b2b-product-actions">
Note: See TracChangeset
for help on using the changeset viewer.