Plugin Directory

Changeset 3429473


Ignore:
Timestamp:
12/30/2025 07:50:24 AM (3 months ago)
Author:
infility
Message:

v2.14.47 (20251230) Ben: 新增和修复导航文章列表

Location:
infility-global/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • infility-global/trunk/infility_global.php

    r3425837 r3429473  
    44Plugin URI: https://www.infility.cn/
    55Description: Infility公共插件
    6 Version: 2.14.46
     6Version: 2.14.47
    77Author: Infility
    88Author URI: https://www.infility.cn/
     
    144144    function __construct()
    145145    {
    146         define( 'INFILITY_GLOBAL_VERSION', '2.14.46' );
     146        define( 'INFILITY_GLOBAL_VERSION', '2.14.47' );
    147147        define( 'INFILITY_GLOBAL_PATH', plugin_dir_path( __FILE__ ) ); // fullpath/wp-content/plugins/infility-global/ // 有斜杠
    148148        define( 'INFILITY_GLOBAL_URL', plugins_url( '/', __FILE__ ) ); // https://the_domain/wp-content/plugins/infility-global/ // 斜杠是自己加的
  • infility-global/trunk/widgets/elementor-tab/css/elementor_nav_posts.css

    r3386744 r3429473  
    248248    text-decoration: none;
    249249    transition: color 0.3s ease;
    250 }
    251 
    252 .infility-nav-posts-widget .post-title a:hover {
    253     color: #007cba;
    254250}
    255251
     
    529525/* 分页链接悬停效果 */
    530526.infility-nav-posts-widget .nav-posts-pagination .page-numbers:hover {
    531     background-color: #005a87 !important;
    532     color: #FFFFFF !important;
     527    /* background-color: #005a87;
     528    color: #FFFFFF; */
    533529    transform: translateY(-1px);
    534530    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  • infility-global/trunk/widgets/elementor-tab/elementor-tab.php

    r3347975 r3429473  
    11<?php
    2 /*↓
    3 Plugin Name: Elementor Tab
    4 Plugin URI:
    5 Description: Elementor 选项卡组件
    6 Version: 1.0
    7 Author:CJJ
    8 Author URI:
    9 License: GPLv2
    10 */
    11 
    12 
    13 class elementor_tab_class{
    14     public function __construct(){
    15 
    16         add_action('wp_enqueue_scripts',array($this,'ETab_load'));         
    17 
    18        
    19         //注册Elementor插件分类
    20         add_action( 'elementor/elements/categories_registered', array($this,'add_elementor_widget_categories') );
    21 
    22         //注册Elementor插件
    23         add_action( 'elementor/widgets/register', array($this,'ETab_elementor_register') );
    24         add_action( 'elementor/widgets/register', array($this,'EBreadcrumb_elementor_register') ); 
    25         // add_action( 'elementor/widgets/register', array($this,'EImgSilde_elementor_register') );
    26         add_action( 'elementor/widgets/register', array($this,'ENavPosts_elementor_register') );
    27 
    28         //AJAX的ACTION
    29         // add_action('wp_ajax_nopriv_get_tertiary_filter_option',array($this,'TF_get_tertiary_filter_option'));   
    30         // add_action('wp_ajax_get_tertiary_filter_option',array($this,'TF_get_tertiary_filter_option'));
    31 
    32         // 注册导航文章列表的AJAX处理函数
    33         add_action('wp_ajax_get_taxonomy_terms', array($this, 'get_taxonomy_terms_ajax'));
    34         add_action('wp_ajax_nopriv_get_taxonomy_terms', array($this, 'get_taxonomy_terms_ajax'));
    35         add_action('wp_ajax_get_taxonomies_for_post_type', array($this, 'get_taxonomies_for_post_type'));
    36         add_action('wp_ajax_nopriv_get_taxonomies_for_post_type', array($this, 'get_taxonomies_for_post_type'));
    37         add_action('wp_ajax_get_posts_for_editor', array($this, 'get_posts_for_editor_ajax'));
    38         add_action('wp_ajax_nopriv_get_posts_for_editor', array($this, 'get_posts_for_editor_ajax'));
    39         add_action('wp_ajax_get_posts_with_pagination', array($this, 'get_posts_with_pagination_ajax'));
    40         add_action('wp_ajax_nopriv_get_posts_with_pagination', array($this, 'get_posts_with_pagination_ajax'));
    41     }
    42 
    43     function add_elementor_widget_categories( $elements_manager ) {
    44 
    45         $elements_manager->add_category(
    46             'infility-category',
    47             [
    48                 'title' => 'Infility',
    49                 'icon' => 'fa fa-plug',
    50             ]
    51         );
    52     }
    53 
    54     function ETab_elementor_register($widgets_manager) {
    55         //选项卡
    56         require_once( __DIR__ . '/includes/widgets/elementor_tab_html.php' );
    57         $widgets_manager->register( new \elementor_tab_html() );
    58     }
    59 
    60     function EBreadcrumb_elementor_register($widgets_manager) {
    61         //面包屑
    62         require_once( __DIR__ . '/includes/widgets/elementor_breadcrumb.php' );
    63         $widgets_manager->register( new \elementor_breadcrumb() );
    64     }
    65 
    66 
    67     function EImgSilde_elementor_register($widgets_manager) {
    68         //图片
    69         require_once( __DIR__ . '/includes/widgets/elementor_img_silde.php' );
    70         $widgets_manager->register( new \elementor_img_silde() );
    71     }
    72 
    73     function ENavPosts_elementor_register($widgets_manager) {
    74         //导航文章列表
    75         require_once( __DIR__ . '/includes/widgets/elementor_nav_posts.php' );
    76         $widgets_manager->register( new \elementor_nav_posts() );
     2
     3if ( ! defined( 'ABSPATH' ) ) {
     4    exit; // Exit if accessed directly
     5}
     6
     7class elementor_nav_posts extends \Elementor\Widget_Base {
     8
     9    /**
     10     * 获取组件名称
     11     */
     12    public function get_name() {
     13        return 'inf_nav_posts';
    7714    }
    7815
    79     function ETab_load(){
    80         wp_enqueue_script('jquery');
    81         wp_enqueue_script('ETab_js',plugins_url('js/elementor_tab.js',__FILE__),['jquery'],false,true);
    82         wp_enqueue_style('ETab_css',plugins_url('css/elementor_tab.css',__FILE__),false);
    83 
    84 
    85         wp_enqueue_style('EBreadcrumb_css',plugins_url('css/elementor_breadcrumb.css',__FILE__),false);
    86         wp_enqueue_style('EImgSilde_css',plugins_url('css/elementor_img_silde.css',__FILE__),false);
    87         wp_enqueue_style('ENavPosts_css',plugins_url('css/elementor_nav_posts.css',__FILE__),false);
    88         wp_enqueue_script('EImgSilde_js',plugins_url('js/elementor_img_silde.js',__FILE__),false,false,true);
    89         wp_enqueue_script('ENavPosts_js',plugins_url('js/elementor_nav_posts.js',__FILE__),['jquery'],false,true);
    90 
    91         // wp_localize_script('TF_js','ajax_object',array('ajax_url'=>  admin_url('admin-ajax.php'))); 
    92     }
    93 
    9416    /**
    95      * AJAX 处理获取分类数据
     17     * 获取组件标题
    9618     */
    97     public function get_taxonomy_terms_ajax() {
    98         // 检查 nonce
    99 //        if (!wp_verify_nonce($_POST['nonce'], 'elementor_nav_posts_nonce')) {
    100 //            wp_die('安全验证失败');
    101 //        }
    102 
    103         $taxonomy_type = sanitize_text_field($_POST['taxonomy_type']);
    104         $custom_taxonomy = sanitize_text_field($_POST['custom_taxonomy']);
    105         $show_hierarchical = sanitize_text_field($_POST['show_hierarchical']);
    106         $post_type = isset($_POST['post_type']) ? sanitize_text_field($_POST['post_type']) : 'post';
    107 
    108         // 确定要使用的分类法
     19    public function get_title() {
     20        return '导航文章列表';
     21    }
     22
     23    /**
     24     * 获取组件图标
     25     */
     26    public function get_icon() {
     27        return 'eicon-posts-grid';
     28    }
     29
     30    /**
     31     * 获取组件分类
     32     */
     33    public function get_categories() {
     34        return ['infility-category'];
     35    }
     36
     37    /**
     38     * 获取组件关键词
     39     */
     40    public function get_keywords() {
     41        return ['导航', '文章', '列表', '分类', 'nav', 'post'];
     42    }
     43
     44    /**
     45     * 注册组件控件
     46     */
     47    protected function register_controls() {
     48        // 内容设置
     49        $this->start_controls_section(
     50            'content_section',
     51            [
     52                'label' => '内容设置',
     53                'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
     54            ]
     55        );
     56
     57        $this->add_control(
     58            'nav_title',
     59            [
     60                'label' => '导航标题',
     61                'type' => \Elementor\Controls_Manager::TEXT,
     62                'default' => 'Category',
     63                'placeholder' => '请输入导航标题',
     64            ]
     65        );
     66
     67        $this->add_control(
     68            'posts_per_page',
     69            [
     70                'label' => '文章数量',
     71                'type' => \Elementor\Controls_Manager::NUMBER,
     72                'default' => 6,
     73                'min' => 1,
     74                'max' => 50,
     75            ]
     76        );
     77
     78        $this->add_responsive_control(
     79            'row_number',
     80            [
     81                'label' => '每行数量',
     82                'type' => \Elementor\Controls_Manager::NUMBER,
     83                'default' => 3,
     84                'min' => 1,
     85                'max' => 10,
     86                'selectors' => [
     87                    '{{WRAPPER}} .posts-grid ' => 'grid-template-columns: repeat({{VALUE}}, 1fr);',
     88                ],
     89            ]
     90        );
     91
     92        $post_types = get_post_types(['has_archive' => true],'objects');
     93        $post_types_options = [];
     94        $post_types_options['post'] = 'post';
     95        foreach ($post_types as $post_type) {
     96            $post_types_options[$post_type->name] = $post_type->label;
     97        }
     98        $this->add_control(
     99            'post_type',
     100            [
     101                'label' => '文章类型',
     102                'type' => \Elementor\Controls_Manager::SELECT,
     103                'default' => 'post',
     104                'options' => $post_types_options,
     105            ]
     106        );
     107
     108
     109        // 获取默认文章类型的分类法
     110        $taxonomies = get_object_taxonomies('post','objects');
     111        $taxonomies_options = [];
     112        $curr = '';
     113        foreach ($taxonomies as $key=>$taxonomy) {
     114            if($key==0){$curr = $taxonomy->name;}
     115            $taxonomies_options[$taxonomy->name] = $taxonomy->label;
     116        }
     117        $taxonomies_options['custom_taxonomy'] = '自定义分类法';
     118
     119        $this->add_control(
     120            'taxonomy_type',
     121            [
     122                'label' => '分类导航类型',
     123                'type' => \Elementor\Controls_Manager::SELECT,
     124                'default' => 'category',
     125                'options' => $taxonomies_options,
     126                'description' => '选择用于导航的分类法类型',
     127                'condition' => [
     128                    'post_type!' => '',
     129                ],
     130                'render_type' => 'template',
     131            ]
     132        );
     133
     134        $this->add_control(
     135            'custom_taxonomy',
     136            [
     137                'label' => '自定义分类法名称',
     138                'type' => \Elementor\Controls_Manager::TEXT,
     139                'default' => '',
     140                'placeholder' => '例如:product_cat, portfolio_category',
     141                'condition' => [
     142                    'taxonomy_type' => 'custom_taxonomy',
     143                ],
     144                'description' => '输入自定义分类法的名称(slug)',
     145            ]
     146        );
     147
     148        $this->add_control(
     149            'show_hierarchical',
     150            [
     151                'label' => '显示多级分类',
     152                'type' => \Elementor\Controls_Manager::SWITCHER,
     153                'default' => 'yes',
     154                'label_on' => '是',
     155                'label_off' => '否',
     156                'description' => '是否显示分类的层级结构',
     157            ]
     158        );
     159
     160        $this->add_control(
     161            'orderby',
     162            [
     163                'label' => '排序方式',
     164                'type' => \Elementor\Controls_Manager::SELECT,
     165                'default' => 'date',
     166                'options' => [
     167                    'date' => '发布日期',
     168                    'title' => '标题',
     169                    'rand' => '随机',
     170                    'comment_count' => '评论数',
     171                ],
     172            ]
     173        );
     174
     175        $this->add_control(
     176            'order',
     177            [
     178                'label' => '排序顺序',
     179                'type' => \Elementor\Controls_Manager::SELECT,
     180                'default' => 'DESC',
     181                'options' => [
     182                    'DESC' => '降序',
     183                    'ASC' => '升序',
     184                ],
     185            ]
     186        );
     187
     188        $this->add_control(
     189            'show_pagination',
     190            [
     191                'label' => '显示分页',
     192                'type' => \Elementor\Controls_Manager::SWITCHER,
     193                'default' => 'yes',
     194                'label_on' => '是',
     195                'label_off' => '否',
     196                'description' => '是否显示分页导航',
     197            ]
     198        );
     199
     200        $this->add_control(
     201            'pagination_type',
     202            [
     203                'label' => '分页类型',
     204                'type' => \Elementor\Controls_Manager::SELECT,
     205                'default' => 'numbers',
     206                'options' => [
     207                    'numbers' => '数字分页',
     208                    'prev_next' => 'Prev/Next',
     209                    'load_more' => 'Load More',
     210                ],
     211                'condition' => [
     212                    'show_pagination' => 'yes',
     213                ],
     214            ]
     215        );
     216
     217        $this->add_control(
     218            'posts_per_page_pagination',
     219            [
     220                'label' => '每页文章数量',
     221                'type' => \Elementor\Controls_Manager::NUMBER,
     222                'default' => 6,
     223                'min' => 1,
     224                'max' => 50,
     225                'condition' => [
     226                    'show_pagination' => 'yes',
     227                ],
     228                'description' => '分页时每页显示的文章数量',
     229            ]
     230        );
     231
     232        $this->end_controls_section();
     233
     234        $this->start_controls_section(
     235            'post_section',
     236            [
     237                'label' => 'Post设置',
     238                'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
     239            ]
     240        );
     241
     242        $this->add_control(
     243            'show_image',
     244            [
     245                'label' => '是否显示图片',
     246                'type' => \Elementor\Controls_Manager::SELECT,
     247                'default' => 'yes',
     248                'options' => [
     249                    'yes' => '是',
     250                    'no' => '否',
     251                ],
     252            ]
     253        );
     254
     255        $this->add_control(
     256            'show_title',
     257            [
     258                'label' => '是否显示标题',
     259                'type' => \Elementor\Controls_Manager::SELECT,
     260                'default' => 'yes',
     261                'options' => [
     262                    'yes' => '是',
     263                    'no' => '否',
     264                ],
     265            ]
     266        );
     267
     268        $this->add_control(
     269            'show_excerpt',
     270            [
     271                'label' => '是否显示摘要',
     272                'type' => \Elementor\Controls_Manager::SELECT,
     273                'default' => 'yes',
     274                'options' => [
     275                    'yes' => '是',
     276                    'no' => '否',
     277                ],
     278            ]
     279        );
     280
     281        $this->add_control(
     282            'show_date',
     283            [
     284                'label' => '是否显示日期',
     285                'type' => \Elementor\Controls_Manager::SELECT,
     286                'default' => 'no',
     287                'options' => [
     288                    'yes' => '是',
     289                    'no' => '否',
     290                ],
     291            ]
     292        );
     293
     294        $this->add_control(
     295            'show_category',
     296            [
     297                'label' => '是否显示分类',
     298                'type' => \Elementor\Controls_Manager::SELECT,
     299                'default' => 'no',
     300                'options' => [
     301                    'yes' => '是',
     302                    'no' => '否',
     303                ],
     304            ]
     305        );
     306
     307        $this->end_controls_section();
     308
     309        // 样式设置 - 导航栏
     310        $this->start_controls_section(
     311            'nav_style_section',
     312            [
     313                'label' => '导航栏样式',
     314                'tab' => \Elementor\Controls_Manager::TAB_STYLE,
     315            ]
     316        );
     317
     318        $this->add_control(
     319            'nav_bg_color',
     320            [
     321                'label' => '导航背景色',
     322                'type' => \Elementor\Controls_Manager::COLOR,
     323                'default' => '#f8f9fa',
     324                'selectors' => [
     325                    '{{WRAPPER}} .nav-posts-nav' => 'background-color: {{VALUE}};',
     326                ],
     327            ]
     328        );
     329
     330        $this->add_control(
     331            'nav_text_color',
     332            [
     333                'label' => '导航文字颜色',
     334                'type' => \Elementor\Controls_Manager::COLOR,
     335                'default' => '#333333',
     336                'selectors' => [
     337                    '{{WRAPPER}} .nav-posts-nav .nav-item' => 'color: {{VALUE}};',
     338                ],
     339            ]
     340        );
     341
     342        $this->add_control(
     343            'nav_active_color',
     344            [
     345                'label' => '激活状态文字颜色',
     346                'type' => \Elementor\Controls_Manager::COLOR,
     347                'default' => '#007cba',
     348                'selectors' => [
     349                    '{{WRAPPER}} .nav-posts-nav .nav-item.active span' => 'color: {{VALUE}};',
     350                ],
     351            ]
     352        );
     353
     354        $this->add_control(
     355            'nav_bg_color_hover_first',
     356            [
     357                'label' => '一级导航hover背景色',
     358                'type' => \Elementor\Controls_Manager::COLOR,
     359                'default' => 'rgba(0, 124, 186, 0.1)',
     360                'selectors' => [
     361                    '{{WRAPPER}} .nav-item:hover' => 'background-color: {{VALUE}};',
     362                ],
     363            ]
     364        );
     365
     366        $this->add_control(
     367            'nav_text_color_hover_first',
     368            [
     369                'label' => '一级导航hover文字色',
     370                'type' => \Elementor\Controls_Manager::COLOR,
     371                'default' => '#000000',
     372                'selectors' => [
     373                    '{{WRAPPER}} .nav-item:hover' => 'color: {{VALUE}};',
     374                ],
     375            ]
     376        );
     377
     378        $this->add_control(
     379            'nav_bg_color_hover_second',
     380            [
     381                'label' => '二级导航hover背景色',
     382                'type' => \Elementor\Controls_Manager::COLOR,
     383                'default' => 'rgba(0, 124, 186, 0.1)',
     384                'selectors' => [
     385                    '{{WRAPPER}} .nav-sub-item:hover' => 'background-color: {{VALUE}};',
     386                ],
     387            ]
     388        );
     389
     390        $this->add_control(
     391            'nav_text_color_hover_second',
     392            [
     393                'label' => '二级导航hover文字色',
     394                'type' => \Elementor\Controls_Manager::COLOR,
     395                'default' => '#000000',
     396                'selectors' => [
     397                    '{{WRAPPER}} .nav-sub-item:hover' => 'color: {{VALUE}};',
     398                ],
     399            ]
     400        );
     401
     402        $this->add_control(
     403            'nav_text_transform',
     404            [
     405                'label' => '导航文字大写设置',
     406                'type' => \Elementor\Controls_Manager::SELECT,
     407                'default' => 'unset',
     408                'options' => [
     409                    'unset' => '不设置',
     410                    'uppercase' => '全大写',
     411                    'capitalize' => '首字母大写',
     412                    'lowercase' => '全小写',
     413                ],
     414                'selectors' => [
     415                    '{{WRAPPER}} .nav-posts-nav .nav-item' => 'text-transform: {{VALUE}};',
     416                    '{{WRAPPER}} .nav-posts-nav .nav-sub-item' => 'text-transform: {{VALUE}};',
     417                ],
     418            ]
     419        );
     420
     421        $this->add_group_control(
     422            \Elementor\Group_Control_Typography::get_type(),
     423            [
     424                'name' => 'nav_typography',
     425                'selector' => '{{WRAPPER}} .nav-posts-nav .nav-item',
     426            ]
     427        );
     428
     429        $this->end_controls_section();
     430
     431        // 样式设置 - 文章列表
     432        $this->start_controls_section(
     433            'posts_style_section',
     434            [
     435                'label' => '文章列表样式',
     436                'tab' => \Elementor\Controls_Manager::TAB_STYLE,
     437            ]
     438        );
     439
     440        $this->add_control(
     441            'post_title_color',
     442            [
     443                'label' => '文章标题颜色',
     444                'type' => \Elementor\Controls_Manager::COLOR,
     445                'default' => '#333333',
     446                'selectors' => [
     447                    '{{WRAPPER}} .nav-posts-content .post-title' => 'color: {{VALUE}};',
     448                ],
     449            ]
     450        );
     451
     452        $this->add_group_control(
     453            \Elementor\Group_Control_Typography::get_type(),
     454            [
     455                'name' => 'post_title_typography',
     456                'label' => '文章标题字体',
     457                'selector' => '{{WRAPPER}} .nav-posts-content .post-title',
     458            ]
     459        );
     460
     461        $this->add_control(
     462            'post_excerpt_color',
     463            [
     464                'label' => '文章摘要颜色',
     465                'type' => \Elementor\Controls_Manager::COLOR,
     466                'default' => '#666666',
     467                'selectors' => [
     468                    '{{WRAPPER}} .nav-posts-content .post-excerpt' => 'color: {{VALUE}};',
     469                ],
     470            ]
     471        );
     472
     473        $this->add_group_control(
     474            \Elementor\Group_Control_Typography::get_type(),
     475            [
     476                'name' => 'post_excerpt_typography',
     477                'label' => '文章摘要字体',
     478                'selector' => '{{WRAPPER}} .nav-posts-content .post-excerpt',
     479            ]
     480        );
     481
     482        $this->add_control(
     483            'post_text_color_hover',
     484            [
     485                'label' => '文章文字悬停颜色',
     486                'type' => \Elementor\Controls_Manager::COLOR,
     487                'default' => '#005a87',
     488                'selectors' => [
     489                     '{{WRAPPER}} .nav-posts-content .post-title a:hover' => 'color: {{VALUE}};',
     490                     '{{WRAPPER}} .nav-posts-content .post-excerpt:hover' => 'color: {{VALUE}};',
     491                ],
     492            ]
     493        );
     494
     495        $this->add_responsive_control(
     496            'box_content_padding',
     497            [
     498                'label'      => '文章文字框内边距',
     499                'type'       => \Elementor\Controls_Manager::DIMENSIONS,
     500                'size_units' => [ 'px', '%', 'em' ],
     501                'selectors'  => [
     502                    '{{WRAPPER}} .post-item .post-content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
     503                ],
     504            ]
     505        );
     506
     507        $this->end_controls_section();
     508
     509        // Box样式设置
     510        $this->start_controls_section(
     511            'box_style_section',
     512            [
     513                'label' => 'Box样式',
     514                'tab' => \Elementor\Controls_Manager::TAB_STYLE,
     515            ]
     516        );
     517
     518        $this->add_responsive_control(
     519            'box_gap',
     520            [
     521                'label'      => '每个box的间距',
     522                'type'       => \Elementor\Controls_Manager::SLIDER,
     523                'size_units' => [ 'px', '%', 'em' ],
     524                'selectors'  => [
     525                    '{{WRAPPER}} .posts-grid' => 'gap:{{SIZE}}{{UNIT}}',
     526                ],
     527            ]
     528        );
     529
     530        $this->add_responsive_control(
     531            'box_padding',
     532            [
     533                'label'      => '内边距',
     534                'type'       => \Elementor\Controls_Manager::DIMENSIONS,
     535                'size_units' => [ 'px', '%', 'em' ],
     536                'selectors'  => [
     537                    '{{WRAPPER}} .post-item' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
     538                ],
     539            ]
     540        );
     541
     542        $this->add_responsive_control(
     543            'box_margin',
     544            [
     545                'label'      => '外边距',
     546                'type'       => \Elementor\Controls_Manager::DIMENSIONS,
     547                'size_units' => [ 'px', '%', 'em' ],
     548                'selectors'  => [
     549                    '{{WRAPPER}} .post-item' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
     550                ],
     551            ]
     552        );
     553
     554        $this->add_group_control(
     555            \Elementor\Group_Control_Border::get_type(),
     556            [
     557                'name'     => 'box_border',
     558                'label'    => '边框',
     559                'selector' => '{{WRAPPER}} .post-item',
     560            ]
     561        );
     562
     563        $this->add_control(
     564            'box_border_radius',
     565            [
     566                'label'      => '边框圆角',
     567                'type'       => \Elementor\Controls_Manager::DIMENSIONS,
     568                'size_units' => [ 'px', '%' ],
     569                'selectors'  => [
     570                    '{{WRAPPER}} .post-item' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
     571                ],
     572            ]
     573        );
     574
     575        $this->add_group_control(
     576            \Elementor\Group_Control_Box_Shadow::get_type(),
     577            [
     578                'name'     => 'box_shadow',
     579                'label'    => '边框阴影',
     580                'selector' => '{{WRAPPER}} .post-item',
     581            ]
     582        );
     583
     584        $this->end_controls_section();
     585
     586
     587        $this->start_controls_section(
     588            'image_style_section',
     589            [
     590                'label' => '图片样式',
     591                'tab' => \Elementor\Controls_Manager::TAB_STYLE,
     592            ]
     593        );
     594
     595        $this->add_control(
     596            'image_resolution',
     597            [
     598                'label' => '图片规格',
     599                'type' => \Elementor\Controls_Manager::SELECT,
     600                'default' => 'large',
     601                'options' => [
     602                    'thumbnail' => 'Thumbnail - 150 x 150',
     603                    'medium' => 'Medium - 300 x 300',
     604                    'medium_large' => 'Medium Large - 768 x 0',
     605                    'large' => 'Large - 1024 x 1024',
     606                    '1536x1536' => '1536x1536 - 1536 x 1536',
     607                    '2048x2048' => '2048x2048 - 2048 x 2048',
     608                    'full' => 'Full',
     609                ],
     610            ]
     611        );
     612
     613        $this->add_control(
     614            'image_height_fixed',
     615            [
     616                'label' => '固定图片高度',
     617                'type' => \Elementor\Controls_Manager::SWITCHER,
     618                'default' => 'no',
     619                'label_on' => '是',
     620                'label_off' => '否',
     621            ]
     622        );
     623
     624        $this->add_responsive_control(
     625            'image_height',
     626            [
     627                'label'      => '图片高度',
     628                'type'       => \Elementor\Controls_Manager::SLIDER,
     629                'size_units' => [ 'px', '%', 'em' ],
     630                'selectors'  => [
     631                    '{{WRAPPER}} .post-thumbnail img' => 'height:{{SIZE}}{{UNIT}}',
     632                ],
     633                'condition' => [
     634                    'image_height_fixed' => 'yes',
     635                ],
     636            ]
     637        );
     638
     639        $this->add_responsive_control(
     640            'image_padding',
     641            [
     642                'label'      => '内边距',
     643                'type'       => \Elementor\Controls_Manager::DIMENSIONS,
     644                'size_units' => [ 'px', '%', 'em' ],
     645                'selectors'  => [
     646                    '{{WRAPPER}} .post-item .post-thumbnail' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
     647                ],
     648            ]
     649        );
     650
     651        $this->add_responsive_control(
     652            'image_margin',
     653            [
     654                'label'      => '外边距',
     655                'type'       => \Elementor\Controls_Manager::DIMENSIONS,
     656                'size_units' => [ 'px', '%', 'em' ],
     657                'selectors'  => [
     658                    '{{WRAPPER}} .post-item .post-thumbnail' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
     659                ],
     660            ]
     661        );
     662
     663        $this->add_group_control(
     664            \Elementor\Group_Control_Border::get_type(),
     665            [
     666                'name'     => 'image_border',
     667                'label'    => '边框',
     668                'selector' => '{{WRAPPER}} .post-item .post-thumbnail',
     669            ]
     670        );
     671
     672        $this->add_control(
     673            'image_border_radius',
     674            [
     675                'label'      => '边框圆角',
     676                'type'       => \Elementor\Controls_Manager::DIMENSIONS,
     677                'size_units' => [ 'px', '%' ],
     678                'selectors'  => [
     679                    '{{WRAPPER}} .post-item .post-thumbnail img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};overflow:hidden;',
     680                ],
     681            ]
     682        );
     683
     684        $this->add_group_control(
     685            \Elementor\Group_Control_Box_Shadow::get_type(),
     686            [
     687                'name'     => 'image_shadow',
     688                'label'    => '边框阴影',
     689                'selector' => '{{WRAPPER}} .post-item .post-thumbnail',
     690            ]
     691        );
     692
     693        $this->add_control(
     694            'image_background_color',
     695            [
     696                'label' => '图片背景色',
     697                'type' => \Elementor\Controls_Manager::COLOR,
     698                'default' => '#FFFFFF00',
     699                'selectors' => [
     700                    '{{WRAPPER}} .post-item .post-thumbnail::after' => 'content: "";position: absolute;inset: 0;background: {{VALUE}};',
     701                ],
     702            ]
     703        );
     704
     705        $this->end_controls_section();
     706
     707        // 样式设置 - 分页
     708        $this->start_controls_section(
     709            'pagination_style_section',
     710            [
     711                'label' => '分页样式',
     712                'tab' => \Elementor\Controls_Manager::TAB_STYLE,
     713                'condition' => [
     714                    'show_pagination' => 'yes',
     715                ],
     716            ]
     717        );
     718
     719        $this->add_control(
     720            'pagination_bg_color',
     721            [
     722                'label' => '分页背景色',
     723                'type' => \Elementor\Controls_Manager::COLOR,
     724                'default' => '#f8f9fa',
     725                'selectors' => [
     726                    '{{WRAPPER}} .nav-posts-pagination .page-numbers' => 'background-color: {{VALUE}};',
     727                ],
     728            ]
     729        );
     730
     731        $this->add_control(
     732            'pagination_text_color',
     733            [
     734                'label' => '分页文字颜色',
     735                'type' => \Elementor\Controls_Manager::COLOR,
     736                'default' => '#333333',
     737                'selectors' => [
     738                    '{{WRAPPER}} .nav-posts-pagination .page-numbers' => 'color: {{VALUE}};',
     739                ],
     740            ]
     741        );
     742
     743        $this->add_control(
     744            'pagination_active_color',
     745            [
     746                'label' => '当前页颜色',
     747                'type' => \Elementor\Controls_Manager::COLOR,
     748                'default' => '#007cba',
     749                'selectors' => [
     750                    '{{WRAPPER}} .nav-posts-pagination .current' => 'color: #FFFFFF;background-color: {{VALUE}};',
     751                ],
     752            ]
     753        );
     754
     755        $this->add_control(
     756            'pagination_hover_color',
     757            [
     758                'label' => '悬停颜色',
     759                'type' => \Elementor\Controls_Manager::COLOR,
     760                'default' => '#005a87',
     761                'selectors' => [
     762                    '{{WRAPPER}} .nav-posts-pagination .page-numbers:hover' => 'color: #FFFFFF;background-color: {{VALUE}};',
     763                ],
     764            ]
     765        );
     766
     767        $this->add_group_control(
     768            \Elementor\Group_Control_Typography::get_type(),
     769            [
     770                'name' => 'pagination_typography',
     771                'selector' => '{{WRAPPER}} .nav-posts-pagination .page-numbers',
     772            ]
     773        );
     774
     775        $this->add_control(
     776            'pagination_spacing',
     777            [
     778                'label' => '分页间距',
     779                'type' => \Elementor\Controls_Manager::SLIDER,
     780                'size_units' => ['px', 'em'],
     781                'range' => [
     782                    'px' => [
     783                        'min' => 0,
     784                        'max' => 50,
     785                        'step' => 1,
     786                    ],
     787                    'em' => [
     788                        'min' => 0,
     789                        'max' => 5,
     790                        'step' => 0.1,
     791                    ],
     792                ],
     793                'default' => [
     794                    'unit' => 'px',
     795                    'size' => 10,
     796                ],
     797                'selectors' => [
     798                    '{{WRAPPER}} .nav-posts-pagination .page-numbers' => 'margin: 0 {{SIZE}}{{UNIT}};',
     799                ],
     800            ]
     801        );
     802
     803        $this->end_controls_section();
     804    }
     805
     806    /**
     807     * 渲染组件
     808     */
     809    protected function render() {
     810        $settings = $this->get_settings_for_display();
     811
     812        // 获取分类
    109813        $taxonomy_name = '';
    110814        $taxonomy_args = [];
    111815
    112         if ($taxonomy_type === 'custom_taxonomy' && !empty($custom_taxonomy)) {
    113             $taxonomy_name = $custom_taxonomy;
    114             $taxonomy_args = [
    115                 'taxonomy' => $taxonomy_name,
    116                 'hide_empty' => true,
    117             ];
     816        if ($settings['taxonomy_type'] === 'custom_taxonomy') {
     817            $taxonomy_name = $settings['custom_taxonomy'];
     818            if (!empty($taxonomy_name)) {
     819                $taxonomy_args = [
     820                    'taxonomy' => $taxonomy_name,
     821                    'hide_empty' => true,
     822                ];
     823            }
    118824        } else {
    119             $taxonomy_name = $taxonomy_type;
     825            $taxonomy_name = $settings['taxonomy_type'];
    120826            $taxonomy_args = [
    121827                'taxonomy' => $taxonomy_name,
     
    124830        }
    125831
    126         // 根据设置决定是否显示层级结构
    127         if ($show_hierarchical === 'yes') {
    128             $taxonomy_args['hierarchical'] = true;
    129         }
    130 
    131832        // 验证分类法是否属于指定的文章类型
     833        $post_type = isset($settings['post_type']) ? $settings['post_type'] : 'post';
    132834        $post_type_taxonomies = get_object_taxonomies($post_type);
    133835        if (!in_array($taxonomy_name, $post_type_taxonomies)) {
    134             wp_send_json_error('分类法不属于指定的文章类型');
    135         }
    136 
    137         $categories = get_terms($taxonomy_args);
    138 
    139         if (is_wp_error($categories)) {
    140             wp_send_json_error('获取分类失败');
    141         }
    142 
    143         // 构建层级结构
    144         $hierarchical_categories = [];
    145         foreach ($categories as $category) {
    146             $hierarchical_categories[] = [
    147                 'term_id' => $category->term_id,
    148                 'name' => $category->name,
    149                 'slug' => $category->slug,
    150                 'parent' => $category->parent,
    151                 'count' => $category->count,
    152             ];
    153         }
    154 
    155         wp_send_json_success($hierarchical_categories);
    156     }
    157 
    158     public function get_taxonomies_for_post_type() {
    159         // 检查 nonce
    160 //        if (!wp_verify_nonce($_POST['nonce'], 'elementor_nav_posts_nonce')) {
    161 //            wp_die('安全验证失败');
    162 //        }
    163 
    164         $post_type = sanitize_text_field($_POST['post_type']);
    165 
    166         // 验证文章类型是否存在
    167         if (!post_type_exists($post_type)) {
    168             wp_send_json_error('文章类型不存在');
    169         }
    170 
    171         $taxonomies = get_object_taxonomies($post_type, 'objects');
    172         $taxonomies_data = [];
    173 
    174         foreach ($taxonomies as $taxonomy) {
    175             if ($taxonomy->public && $taxonomy->show_ui) {
    176                 $taxonomies_data[] = [
    177                     'name' => $taxonomy->name,
    178                     'label' => $taxonomy->label
     836            // 如果分类法不属于指定文章类型,使用默认分类法
     837            $default_taxonomies = get_object_taxonomies($post_type);
     838            if (!empty($default_taxonomies)) {
     839                $taxonomy_name = $default_taxonomies[0];
     840                $taxonomy_args = [
     841                    'taxonomy' => $taxonomy_name,
     842                    'hide_empty' => true,
    179843                ];
    180844            }
    181845        }
    182846
    183         wp_send_json_success($taxonomies_data);
     847        // 根据设置决定是否显示层级结构
     848        if ($settings['show_hierarchical'] === 'yes') {
     849            $taxonomy_args['hierarchical'] = true;
     850        }
     851
     852        $categories = get_terms($taxonomy_args);
     853
     854        // 获取文章
     855        $posts_per_page = $settings['show_pagination'] === 'yes' ? $settings['posts_per_page_pagination'] : $settings['posts_per_page'];
     856        $paged = get_query_var('paged') ? get_query_var('paged') : 1;
     857
     858        $posts_query = new WP_Query([
     859            'post_type' => $settings['post_type'],
     860            'posts_per_page' => $posts_per_page,
     861            'orderby' => $settings['orderby'],
     862            'order' => $settings['order'],
     863            'paged' => $paged,
     864        ]);
     865
     866        // 渲染HTML结构
     867        $this->render_html_structure($settings, $categories, $posts_query);
     868
     869        // 渲染JavaScript代码
     870        $this->render_javascript($settings);
    184871    }
    185872
    186873    /**
    187      * AJAX 处理获取文章数据(用于编辑器预览)
     874     * 渲染组件内容(用于编辑器预览)
    188875     */
    189     public function get_posts_for_editor_ajax() {
    190         // 检查 nonce
    191 //        if (!wp_verify_nonce($_POST['nonce'], 'elementor_nav_posts_nonce')) {
    192 //            wp_die('安全验证失败');
    193 //        }
    194 
    195         $post_type = sanitize_text_field($_POST['post_type']);
    196         $posts_per_page = intval($_POST['posts_per_page']);
    197         $orderby = sanitize_text_field($_POST['orderby']);
    198         $order = sanitize_text_field($_POST['order']);
    199 
    200         // 验证文章类型是否存在
    201         if (!post_type_exists($post_type)) {
    202             wp_send_json_error('文章类型不存在');
    203         }
    204 
    205         // 构建查询参数
    206         $args = [
    207             'post_type' => $post_type,
    208             'posts_per_page' => $posts_per_page,
    209             'orderby' => $orderby,
    210             'order' => $order,
    211             'post_status' => 'publish',
    212         ];
    213 
    214         $posts_query = new WP_Query($args);
    215         $posts_data = [];
    216 
    217         if ($posts_query->have_posts()) {
    218             while ($posts_query->have_posts()) {
    219                 $posts_query->the_post();
    220 
    221                 // 获取文章缩略图
    222                 $thumbnail = '';
    223                 if (has_post_thumbnail()) {
    224                     $thumbnail_id = get_post_thumbnail_id();
    225                     $thumbnail = wp_get_attachment_image_src($thumbnail_id, 'medium')[0];
    226                 } else {
    227                     // 使用默认占位图
    228                     $thumbnail = plugins_url('images/placeholder.jpg', __FILE__);
    229                 }
    230 
    231                 // 获取文章分类
    232                 $terms = [];
    233                 $post_taxonomies = get_object_taxonomies($post_type);
    234                 if (!empty($post_taxonomies)) {
    235                     $post_terms = wp_get_post_terms(get_the_ID(), $post_taxonomies[0]);
    236                     if (!is_wp_error($post_terms)) {
    237                         foreach ($post_terms as $term) {
    238                             $terms[] = $term->name;
    239                         }
     876    protected function content_template() {
     877        ?>
     878        <div class="infility-nav-posts-widget">
     879            <div class="nav-posts-container">
     880                <!-- 左边导航栏 -->
     881                <div class="nav-posts-nav">
     882                    <h3 class="nav-title show">
     883                        <span>{{{ settings.nav_title }}}</span>
     884                        <i class="open"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 16L6 10H18L12 16Z"></path></svg></i>
     885                        <i class="close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M16 12L10 18V6L16 12Z"></path></svg></i>
     886                    </h3>
     887                    <ul class="nav-list">
     888                        <li class="nav-item active" data-category="all">
     889                            <span>All</span>
     890                        </li>
     891
     892                        <!-- 动态分类导航 -->
     893                        <div class="nav-categories-container">
     894                            <!-- 分类将通过 AJAX 动态加载 -->
     895                        </div>
     896                    </ul>
     897                </div>
     898
     899                <!-- 右边文章列表 -->
     900                <div class="nav-posts-content">
     901                    <div class="posts-grid">
     902                        <!-- 文章将通过 AJAX 动态加载 -->
     903                    </div>
     904
     905                    <!-- 分页将通过 AJAX 动态加载 -->
     906                    <div class="nav-posts-pagination">
     907                        <!-- 分页将通过 AJAX 动态加载 -->
     908                    </div>
     909                </div>
     910            </div>
     911        </div>
     912
     913        <script>
     914            jQuery(document).ready(function($) {
     915                // 获取当前组件的设置
     916                var settings = {
     917                    post_type: '{{{ settings.post_type }}}',
     918                    taxonomy_type: '{{{ settings.taxonomy_type }}}',
     919                    custom_taxonomy: '{{{ settings.custom_taxonomy }}}',
     920                    show_hierarchical: '{{{ settings.show_hierarchical }}}',
     921                    posts_per_page: '{{{ settings.posts_per_page }}}',
     922                    row_number: '{{{ settings.row_number }}}',
     923                    orderby: '{{{ settings.orderby }}}',
     924                    order: '{{{ settings.order }}}',
     925                    show_pagination: '{{{ settings.show_pagination }}}',
     926                    pagination_type: '{{{ settings.pagination_type }}}',
     927                    posts_per_page_pagination: '{{{ settings.posts_per_page_pagination }}}',
     928                    show_image: '{{{ settings.show_image }}}',
     929                    image_resolution: '{{{ settings.image_resolution }}}',
     930                    show_title: '{{{ settings.show_title }}}',
     931                    show_excerpt: '{{{ settings.show_excerpt }}}',
     932                    show_date: '{{{ settings.show_date }}}',
     933                    show_category: '{{{ settings.show_category }}}'
     934                };
     935
     936                // 动态联动功能
     937                function initDynamicLinking() {
     938                    // 方法1: 使用Elementor的hooks
     939                    if (typeof elementor !== 'undefined' && elementor.hooks) {
     940                        updateTaxonomies(settings.post_type);
    240941                    }
    241942                }
    242943
    243                 $posts_data[] = [
    244                     'ID' => get_the_ID(),
    245                     'title' => get_the_title(),
    246                     'excerpt' => wp_trim_words(get_the_excerpt(), 20),
    247                     'date' => get_the_date(),
    248                     'thumbnail' => $thumbnail,
    249                     'terms' => $terms,
    250                     'permalink' => get_permalink(),
    251                 ];
    252             }
    253         }
    254 
    255         wp_reset_postdata();
    256         wp_send_json_success($posts_data);
     944                function updateTaxonomies(postType) {
     945                    var panel = elementor.getPanelView();
     946                    var taxonomyControl = panel.content.currentView.collection.findWhere({ name: 'taxonomy_type' });
     947
     948                    $.ajax({
     949                        url: window.ajaxurl || '/wp-admin/admin-ajax.php',
     950                        type: 'POST',
     951                        data: {
     952                            action: 'get_taxonomies_for_post_type',
     953                            post_type: postType,
     954                            nonce: window.elementor_nav_posts_nonce || ''
     955                        },
     956                        success: function(response) {
     957                            var options = {};
     958                            if(response.data){
     959                                for (var i = 0; i < response.data.length; i++) {
     960                                    var taxonomy = response.data[i];
     961                                    options[taxonomy.name] = taxonomy.label;
     962                                }
     963                            }
     964                            options['custom_taxonomy'] = '自定义分类法';
     965
     966                            taxonomyControl.set('options', options); // 更新 options
     967                            taxonomyControl.set('value', response.data[0].name); // 默认选中第一个
     968                            // panel.content.currentView.render();
     969                            panel.getCurrentPageView()._renderChildren();
     970                        },
     971                        error: function(err) {
     972                            taxonomyControl.set('options', {});
     973                            taxonomyControl.set('value', '');
     974                        }
     975                    });
     976                }
     977
     978                // 初始化动态联动功能
     979                initDynamicLinking();
     980
     981                // 初始化组件
     982                initNavPostsWidget(settings);
     983            });
     984        </script>
     985        <?php
    257986    }
    258987
    259988    /**
    260      * AJAX 处理获取文章数据和分页信息(用于编辑器预览)
     989     * 渲染HTML结构
    261990     */
    262     public function get_posts_with_pagination_ajax() {
    263         // 检查 nonce
    264 //        if (!wp_verify_nonce($_POST['nonce'], 'infility_nav_posts_nonce')) {
    265 //            wp_die('安全验证失败');
    266 //        }
    267 
    268         $category = sanitize_text_field($_POST['category']);
    269         $post_type = sanitize_text_field($_POST['post_type']);
    270         $posts_per_page = intval($_POST['posts_per_page']);
    271         $orderby = sanitize_text_field($_POST['orderby']);
    272         $order = sanitize_text_field($_POST['order']);
    273         $show_pagination = sanitize_text_field($_POST['show_pagination']);
    274         $image_resolution = sanitize_text_field($_POST['image_resolution']);
    275         $pagination_type = sanitize_text_field($_POST['pagination_type']);
    276         $paged = isset($_POST['paged']) ? intval($_POST['paged']) : 1;
    277 
    278         // 验证文章类型是否存在
    279         if (!post_type_exists($post_type)) {
    280             wp_send_json_error('文章类型不存在');
    281         }
    282 
    283         // 构建查询参数
    284         $args = [
    285             'post_type' => $post_type,
    286             'posts_per_page' => $posts_per_page,
    287             'orderby' => $orderby,
    288             'order' => $order,
    289             'post_status' => 'publish',
    290             'paged' => $paged,
    291         ];
    292 
    293         // 如果分类不是"all",添加分类过滤
    294         if ($category !== 'all') {
    295             // 获取文章类型的默认分类法
    296             $taxonomies = get_object_taxonomies($post_type);
    297             if (!empty($taxonomies)) {
    298                 $taxonomy = $taxonomies[0]; // 使用第一个分类法
    299 
    300                 // 检查是否是一级分类,如果是则包含其子分类
    301                 $term = get_term($category, $taxonomy);
    302                 if (!is_wp_error($term)) {
    303                     // 获取该分类的所有子分类
    304                     $child_terms = get_terms([
    305                         'taxonomy' => $taxonomy,
    306                         'parent' => $category,
    307                         'hide_empty' => false,
    308                     ]);
    309 
    310                     $category_ids = [$category];
    311                     foreach ($child_terms as $child_term) {
    312                         $category_ids[] = $child_term->term_id;
    313                     }
    314 
    315                     $args['tax_query'] = [
    316                         [
    317                             'taxonomy' => $taxonomy,
    318                             'field' => 'term_id',
    319                             'terms' => $category_ids,
    320                             'operator' => 'IN',
    321                         ]
    322                     ];
     991    private function render_html_structure($settings, $categories, $posts_query) {
     992        ?>
     993        <div class="infility-nav-posts-widget">
     994            <div class="nav-posts-container">
     995                <!-- 左边导航栏 -->
     996                <div class="nav-posts-nav">
     997                    <h3 class="nav-title show">
     998                        <span><?php echo esc_html($settings['nav_title']); ?></span>
     999                        <i class="open"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 16L6 10H18L12 16Z"></path></svg></i>
     1000                        <i class="close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M16 12L10 18V6L16 12Z"></path></svg></i>
     1001                    </h3>
     1002                    <ul class="nav-list">
     1003                        <li class="nav-item active" data-category="all">
     1004                            <span>All</span>
     1005                        </li>
     1006
     1007                        <!-- 动态分类导航 -->
     1008                        <div class="nav-categories-container">
     1009                            <!-- 分类将通过 AJAX 动态加载 -->
     1010                        </div>
     1011                    </ul>
     1012                </div>
     1013
     1014                <!-- 右边文章列表 -->
     1015                <div class="nav-posts-content">
     1016                    <div class="posts-grid">
     1017                        <!-- 文章将通过 AJAX 动态加载 -->
     1018                    </div>
     1019
     1020                    <!-- 分页将通过 AJAX 动态加载 -->
     1021                    <div class="nav-posts-pagination">
     1022                        <!-- 分页将通过 AJAX 动态加载 -->
     1023                    </div>
     1024                </div>
     1025            </div>
     1026        </div>
     1027        <?php
     1028    }
     1029
     1030    /**
     1031     * 渲染JavaScript代码
     1032     */
     1033    private function render_javascript($settings) {
     1034        ?>
     1035        <script>
     1036            // 设置全局变量供JavaScript使用
     1037            window.ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
     1038            window.elementor_nav_posts_nonce = '<?php echo wp_create_nonce('elementor_nav_posts_nonce'); ?>';
     1039
     1040            jQuery(document).ready(function($) {
     1041                // 获取当前组件的设置
     1042                var settings = {
     1043                    post_type: '<?php echo esc_js($settings['post_type']); ?>',
     1044                    taxonomy_type: '<?php echo esc_js($settings['taxonomy_type']); ?>',
     1045                    custom_taxonomy: '<?php echo esc_js($settings['custom_taxonomy']); ?>',
     1046                    show_hierarchical: '<?php echo esc_js($settings['show_hierarchical']); ?>',
     1047                    posts_per_page: '<?php echo esc_js($settings['posts_per_page']); ?>',
     1048                    row_number: '<?php echo esc_js($settings['row_number']); ?>',
     1049                    orderby: '<?php echo esc_js($settings['orderby']); ?>',
     1050                    order: '<?php echo esc_js($settings['order']); ?>',
     1051                    show_pagination: '<?php echo esc_js($settings['show_pagination']); ?>',
     1052                    pagination_type: '<?php echo esc_js($settings['pagination_type']); ?>',
     1053                    posts_per_page_pagination: '<?php echo esc_js($settings['posts_per_page_pagination']); ?>',
     1054                    show_image: '<?php echo esc_js($settings['show_image']); ?>',
     1055                    image_resolution: '<?php echo esc_js($settings['image_resolution']); ?>',
     1056                    show_title: '<?php echo esc_js($settings['show_title']); ?>',
     1057                    show_excerpt: '<?php echo esc_js($settings['show_excerpt']); ?>',
     1058                    show_date: '<?php echo esc_js($settings['show_date']); ?>',
     1059                    show_category: '<?php echo esc_js($settings['show_category']); ?>'
     1060                };
     1061
     1062                // 检查是否有有效的设置
     1063                if (!settings.post_type || settings.post_type === '') {
     1064                    return;
    3231065                }
    324             }
    325         }
    326 
    327         $posts_query = new WP_Query($args);
    328         $posts_data = [];
    329 
    330         if ($posts_query->have_posts()) {
    331             while ($posts_query->have_posts()) {
    332                 $posts_query->the_post();
    333 
    334                 // 获取文章缩略图
    335                 $thumbnail = '';
    336                 $image_resolution = !empty($image_resolution)?$image_resolution:'large';
    337                 if (has_post_thumbnail()) {
    338                     $thumbnail_id = get_post_thumbnail_id();
    339                     $thumbnail = wp_get_attachment_image_src($thumbnail_id, $image_resolution)[0];
    340                 } else {
    341                     // 使用默认占位图
    342                     $thumbnail = plugins_url('images/placeholder.jpg', __FILE__);
     1066
     1067                // 动态联动功能(仅在前端页面)
     1068                function initFrontendDynamicLinking() {
     1069                    // 在前端页面,我们主要关注文章显示,不需要编辑器联动
    3431070                }
    3441071
    345                 // 获取文章分类
    346                 $terms = [];
    347                 $post_taxonomies = get_object_taxonomies($post_type);
    348                 if (!empty($post_taxonomies)) {
    349                     $post_terms = wp_get_post_terms(get_the_ID(), $post_taxonomies[0]);
    350                     if (!is_wp_error($post_terms)) {
    351                         foreach ($post_terms as $term) {
    352                             $terms[] = $term->name;
    353                         }
    354                     }
    355                 }
    356 
    357                 $posts_data[] = [
    358                     'ID' => get_the_ID(),
    359                     'title' => get_the_title(),
    360                     'excerpt' => wp_trim_words(get_the_excerpt(), 20),
    361                     'date' => get_the_date(),
    362                     'thumbnail' => $thumbnail,
    363                     'terms' => $terms,
    364                     'permalink' => get_permalink(),
    365                 ];
    366             }
    367         }
    368 
    369         // 构建分页数据
    370         $pagination_data = null;
    371         if ($show_pagination === 'yes' && $posts_query->max_num_pages > 1) {
    372             $current_page = $paged;
    373             $total_pages = $posts_query->max_num_pages;
    374 
    375             // 构建分页数据
    376             $pagination_data = [
    377                 'current_page' => $current_page,
    378                 'total_pages' => $total_pages,
    379                 'prev_page' => $current_page > 1,
    380                 'next_page' => $current_page < $total_pages,
    381                 'pages' => []
    382             ];
    383 
    384             // 生成页码数组
    385             $start_page = max(1, $current_page - 2);
    386             $end_page = min($total_pages, $current_page + 2);
    387 
    388             for ($i = $start_page; $i <= $end_page; $i++) {
    389                 $pagination_data['pages'][] = [
    390                     'number' => $i,
    391                     'current' => $i == $current_page
    392                 ];
    393             }
    394         }
    395 
    396         wp_reset_postdata();
    397         wp_send_json_success([
    398             'posts' => $posts_data,
    399             'pagination' => $pagination_data
    400         ]);
     1072                // 初始化前端动态联动功能
     1073                initFrontendDynamicLinking();
     1074
     1075                // 初始化组件
     1076                initNavPostsWidget(settings);
     1077            });
     1078        </script>
     1079        <?php
    4011080    }
    4021081}
    403 new elementor_tab_class();
Note: See TracChangeset for help on using the changeset viewer.