作者: admin

  • wordpress 自定义文章类型添加分类筛选功能

    想实现的效果如下图:

    自定义文章类型添加分类筛选功能

    代码如下:

    <?php
    add_action('restrict_manage_posts', 'product_type_filter');
    function product_type_filter() {
        global $typenow;
        $post_type = 'product'; // 发布类型
        $taxonomy = 'product_category'; // 该类型对应的分类法
        if ($typenow == $post_type) {
            $selected = isset($_GET[$taxonomy]) ? $_GET[$taxonomy] : '';
            $info_taxonomy = get_taxonomy($taxonomy);
            wp_dropdown_categories(array(
                'show_option_all' => __("所有{$info_taxonomy->label}"),
                'taxonomy' => $taxonomy,
                'name' => $taxonomy,
                'orderby' => 'name',
                'selected' => $selected,
                'value_field' => 'slug',
                'show_count' => true,
                'hide_empty' => true,
            ));
        };
    }
  • wordpress 自定义文章类型的固定链接

    自定义文章类型无法在后台设置固定链接格式,可以在 functions.php 中通过代码来实现。代码如下:

    <?php
    /**
     * 实现 solution 文章类型的 URL 重写
     */
    add_filter('post_type_link', 'custom_solution_link', 1, 3);
    function custom_solution_link($link, $post) {
        if ($post->post_type == 'solution') {
            return home_url('solution/' . $post->ID . '.html');
        } else {
            return $link;
        }
    }
    

    比较重要的一点:

    代码添加完成后,一定要在后台 “ 固定链接设置” 页面,点击一下 “保存更改” 按钮才能生效!!

  • 使用PHP内置服务器运行wordpress造成的404问题

    使用内置服务器时,无法把请求转到发 index.php 。可以通过新加一个 routing.php 文件来实现该功能。

    运行 wordpress 时使用如下命令:

    E:\php\php-7.4.29-Win32-vc15-x64\php.exe -S localhost:80 routing.php

    routing.php文件的内容如下:

    <?php
    $root = $_SERVER['DOCUMENT_ROOT'];
    $path = '/' . ltrim(parse_url(urldecode($_SERVER['REQUEST_URI']))['path'], '/');
    if (file_exists($root . $path)) {
        // Enforces trailing slash, keeping links tidy in the admin
        if (is_dir($root . $path) && substr($path, -1) !== '/') {
            header("Location: $path/");
            exit;
        }
    
        // Runs PHP file if it exists
        if (strpos($path, '.php') !== false) {
            chdir(dirname($root . $path));
            require_once $root . $path;
        } else {
            return false;
        }
    } else {
        // Otherwise, run `index.php`
        chdir($root);
        require_once 'index.php';
    }
    

    参考:

    https://old.romaricpascal.is/writing-about/running-worpdress-with-php-built-in-server

  • wordpress 获取某分类下的文章列表

    可以直接使用WP_Query函数进行查询,代码如下:

    <?php
    $query = new WP_Query([
        'post_type' => 'product',
        'posts_per_page' => 999,
        'order' => 'ASC',
        'tax_query' => [
            [
                'taxonomy' => 'product_category',
                'field' => 'term_id',
                'terms' => $sub->term_id,
            ]
        ],
    ]);
    
    if ($query->have_posts()) :
        while ($query->have_posts()) :
            $query->the_post();
    ?>
    
            <a href="<?php the_permalink() ?>"><?php the_title() ?></a>
    
    <?php
        endwhile;
    endif;
    wp_reset_query();
    ?>
    

    除了使用WP_Query方法外,还可以使用`query_posts`函数,如下:

    <?php
    $paged = 1;
    if (get_query_var('page')) {
        $paged = get_query_var('page');
    }
    query_posts(array(
        'post_type'      => 'case',  // post type
        'paged'          => $paged,  // 当前是第几页
        'posts_per_page' => 9        // 每页几条
    ));
    while (have_posts()) :
        the_post();
    ?>
        <a href="<?php the_permalink() ?>"> <?php the_title() ?> </a>
    <?php endwhile; ?>

    查询wordpress自带的默认文章类型(post):

    <?php
    query_posts(array(
        'category_name' => 'news', // 分类slug
        'posts_per_page' => 6, // 查询几条
    ));
    while (have_posts()) :
        the_post();
    ?>
        <a href="<?php the_permalink() ?>"> <?php the_title() ?> </a>
    <?php endwhile; ?>

    该查询默认是按发布时间倒序排序。

  • wordpress 查询多少天内发布的文章

    该功能通过添加一个posts_where过滤器来完成:

    <?php
    function filter_where($where = '') {
        $where .= " AND post_date > '" . date('Y-m-d', strtotime('-60 days')) . "'";
        return $where;
    }
    add_filter('posts_where', 'filter_where');
    query_posts($query_string);
    ?>
    

    默认是60天内的文章,可更根据需要调整。

    将代码添加到主循环的上面。

    项目中的具体代码如下:

    <?php
    // 查询多少天内的文章
    if (isset($_GET['arttime'])) {
        function filter_where($where = '') {
            $arttime = $_GET['arttime'];
            $where .= " AND post_date > '" . date('Y-m-d', strtotime('-' . $arttime . 'days')) . "'";
            return $where;
        }
        add_filter('posts_where', 'filter_where');
    }
    
    $paged = 1;
    if (get_query_var('page')) {
        $paged = get_query_var('page');
    }
    $term = get_queried_object();
    query_posts(array(
        'category_name'     => $term->slug, // 分类slug
        'posts_per_page'    => 10, // 每页几条
        'paged'             => $paged,  // 当前是第几页
    ));
    while (have_posts()) :
        the_post();
    ?>
        <a href="<?php the_permalink() ?>" class="news-item">
            <div class="left-newlist-left">
                <span> <?php single_cat_title() ?> <i></i><?php echo get_the_date('Y-m-d'); ?></span>
                <h1><?php the_title() ?></h1>
    
            </div>
            <div class="right-newlist-img">
                <img src="<?php echo catch_that_image(); ?>" alt="">
            </div>
        </a>
    <?php endwhile; ?>
    

  • Mariadb 配置远程访问

    执行命令:

    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;

    编辑:vi /etc/mysql/mariadb.conf.d/50-server.cnf

    注释掉下面的行(在前面加#)

    # bind-address            = 127.0.0.1

    最后重启服务

    systemctl restart mysql

    如果找不到该配置在哪个文件里面,可以通过如下命令进行查找:

     grep -r "bind-address" /etc/mysql/*

  • 解决 Nginx SSL 证书报错

    闲来无事,查看了一下 nginx 的 error.log 日志文件,发现里面大量的报错信息:cannot load certificate “data:”: PEM_read_bio_X509_AUX() failed (SSL: error:0909006C:PEM routines:get_name:no start line:Expecting: TRUSTED CERTIFICATE) while SSL handshaking…

    是 ssl 证书报错了,想了一下,整个服务器只有这个博客使用了 https ,理所当然的从博客的 nginx 配置文件和证书文件入手,历时三天也没找到原因,甚至一度把证书都更换了,从腾讯云的 SSL 证书换到了阿里云的 SSL 证书,结果还是报错,说明证书没问题。

    就在快要放弃的时候,突然想到,之前为了屏蔽直接从 ip 来的请求,加了一些配置,屏蔽了http://iphttps://ip两种访问形式,而屏蔽 https+ip 也涉及到了 SSL 证书的问题,当时是通过 map 映射给了一个空证书,会不会是这个原因?

    于是,为了验证这个猜想,把博客站点的错误日志和其它站点的分开,单独统计。过了一夜,第二天打开日志文件查看,果然,博客的错误日志中并没有此错误,只有 error.log 里面有,这就说明错误不是博客站点的 SSL 证书引起的,那么只可能是之前屏蔽 https+ip 的配置引起的。

    找到了原因,那么解决起来就快了。

    先帖一下之前的配置:

    map "" $empty {
        default "";
    }
    server {
        listen 80 default_server;
        listen 443 ssl http2 default_server;
        listen [::]:80 default_server;
        listen [::]:443 ssl http2 default_server;
        server_name _;
    
        ssl_ciphers aNULL;
        ssl_certificate data:$empty;
        ssl_certificate_key data:$empty;
        return 444;
    }

    把上面的配置改成如下:

    # 禁止直接通过IP访问网站
    server {
        listen 80 default_server;
        server_name _;
        return 444;
    }

    删除了屏蔽 https+ip 的配置,只保留屏蔽 http+ip 的配置。然后在博客站点的 nginx 配置文件中添加如下代码:

    # 通过 default_server 把博客站点设置为默认的 https 站点
    listen 443 ssl http2 default_server;
    
    if ($host != 'wujie.me') {
        rewrite ^/(.*)$ https://wujie.me/$1 permanent;
        break;
    }

    把直接从非域名来的请求(包括从 ip 来的请求)跳转到域名就可以了。

    这样修改后,经过两天的观察,没有再出现错误,问题解决!

  • 替换WordPress的Gravatar服务

    最近发现博客的 Gravatar 头像显示不出来了,顺手做了个小插件,用于替换 WordPress 的默认头像服务。

    if ( ! function_exists( 'get_mirror_avatar' ) ) {
        function get_mirror_avatar( $avatar ) {
            // 新 Gravatar 头像源,可自行修改
    
            //$new_gravatar_sever = 'gravatar.loli.net/avatar/';
            //$new_gravatar_sever = 'sdn.geekzu.org/avatar/';  
            //$new_gravatar_sever = 'gravatar.zunhuyun.com/avatar/';  
            $new_gravatar_sever = 'gravatar.kuibu.net/avatar/';  
    
            // 如果实在不行,就换cravatar.cn吧 文档:https://cravatar.com/developer/for-wordpress#more-53
    
            $sources = array(
                'www.gravatar.com/avatar/',
                '0.gravatar.com/avatar/',
                '1.gravatar.com/avatar/',
                '2.gravatar.com/avatar/',
                'secure.gravatar.com/avatar/',
                'cn.gravatar.com/avatar/',
                'gravatar.com/avatar/',
            );
            return str_replace( $sources, $new_gravatar_sever, $avatar );
        }
        add_filter( 'get_avatar', 'get_mirror_avatar' );
    }
    
  • VHDX磁盘格式转换为VMDK

    可以使用 qemu-img.exe 来转换,qemu-img.exe 下载地址:https://cloudbase.it/downloads/qemu-img-win-x64-2_3_0.zip

    转换命令如下:

    qemu-img.exe convert "Windows Server 2012 R2.vhdx" -O vmdk "Windows Server 2012 R2.vmdk"

  • Debian 10 PHP 7.4编译安装imagick扩展

    下载 imagick 源码,解压并进入目录

    wget https://pecl.php.net/get/imagick-3.4.4.tgz
    tar xf imagick-3.4.4.tgz
    cd imagick-3.4.4

    安装依赖

    apt install -y libmagickcore-dev libmagickwand-dev autoconf

    进入 imagick 代码目录后执行 phpize

    /usr/local/php/php74/bin/phpize

    配置

    ./configure --with-php-config=/usr/local/php/php74/bin/php-config --with-imagick=/usr/local/imagemagick

    编译安装

    make && make install

    编译安装完成后会显示扩展模块编译到了哪个目录,记录下这个目录的路径,以便在 php.ini 中进行配置,我这里是 /usr/local/php/php74/lib/php/extensions/no-debug-non-zts-20190902/

    配置 php.ini

    extension_dir = "/usr/local/php/php74/lib/php/extensions/no-debug-non-zts-20190902/"
    extension=imagick.so

    保存并退出,重启 php-fpm 即可。