WordPress在archive.php页面获取文章列表

除了使用WP_Query函数之外,还可以使用query_posts函数来查询,如下:

<?php
query_posts(array(
    'post_type'   => 'case', // You can add a custom post type if you like
    'paged'     => get_query_var('paged', 1),
    'posts_per_page' => 1
));

while (have_posts()) :
    the_post();
?>
    <a href="<?php the_permalink() ?>" class="col-xs-12 col-sm-4 col-md-4 col-lg-4 block-four-list">
        <div class="block-four-list-wrap">
            <img src="<?php echo catch_that_image(); ?>" alt="">
            <div class="infos-right-view2 about-a-infos">
                <h5>成功案例</h5>
                <h1><?php the_title() ?></h1>
                <span class="a-more-4">了解更多<i class="iconfont icon-youjiantou6"></i></span>
            </div>
        </div>
    </a>


<?php
endwhile;

?>

WordPress修改默认发布类型(post)的一些参数

<?php
add_action('init', 'cp_change_post_object');
// Change dashboard Posts to News
function cp_change_post_object() {
    $get_post_type = get_post_type_object('post');
    $labels = $get_post_type->labels;
    //$labels->name = 'News';
    $labels->singular_name = '新闻资讯';
    // $labels->add_new = 'Add News';
    // $labels->add_new_item = 'Add News';
    // $labels->edit_item = 'Edit News';
    // $labels->new_item = 'News';
    // $labels->view_item = 'View News';
    // $labels->search_items = 'Search News';
    // $labels->not_found = 'No News found';
    // $labels->not_found_in_trash = 'No News found in Trash';
    // $labels->all_items = 'All News';
    // $labels->menu_name = 'News';
    // $labels->name_admin_bar = 'News';
}

WordPress搜索功能的制作

首先要创建一个搜索表单,示例代码如下:

<form method="get" action="" onsubmit="return checkForm();">
    <input type="text" placeholder="搜索" name="s" value="<?php the_search_query(); ?>">
    <button type="submit">
        <i class="iconfont icon-sousuo"></i>
    </button>
</form>

表单要注意的是,搜索关键词输入框的name一定要为s,不然wordpress识别不了,也就进不了search.php模板页面。

这样,在点击搜索按钮后,wordpress就会自动跳转到search.php模板页面。

search.php主要代码参考:

<div class="met-news-list" m-id="noset">
    <ul class="ulstyle met-pager-ajax imagesize" data-scale="400x400">
        <?php
        $paged = 1;
        if (get_query_var('page')) {
            $paged = get_query_var('page');
        }
        $s = get_search_query();
        $args = array(
            's' => $s,
            'paged' => $paged,
            'posts_per_page' => 20
        );

        // The Query
        $the_query = new WP_Query($args);
        if ($the_query->have_posts()) {
            while ($the_query->have_posts()) {
                $the_query->the_post();
        ?>
                <li>
                    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                </li>

                <li class="media media-lg border-bottom1">
                    <div class="media-left">
                        <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
                            <img class="media-object" src="<?php echo catch_that_image(); ?>" alt="<?php the_title(); ?>" height="100" />
                        </a>
                    </div>
                    <div class="media-body">
                        <h4> <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>" target="_self"><?php the_title(); ?></a> </h4>
                    </div>
                </li>

            <?php
            }
        } else {
            ?>
            <!--未找到任何搜索结果-->

        <?php }
        ?>
    </ul>
    <div class="m-t-20 text-xs-center hidden-sm-down" m-type="nosysdata">
        共<strong><?php echo $the_query->max_num_pages; ?></strong>页 <strong><?php echo $wp_query->found_posts; ?></strong>条
    </div>
    <?php bootstrap_pagination($the_query); ?>
</div>

WordPress获取文章内的第一张图片

<?php
// 获取文章第一张图片

function catch_that_image() {
    global $post, $posts;
    $first_img = '';
    ob_start();
    ob_end_clean();
    $output = preg_match_all('/<img.+?src=[\'"]([^\'"]+)[\'"].*?>/i', $post->post_content, $matches);
    $first_img = $matches[1][0];
    if (empty($first_img)) {
        $first_img = "/path/to/default.png";
    }
    return $first_img;
}

改进版,增加了默认图片的显示,以及文章中没有图片时的判断:

<?php
// 获取文章第一张图片
function catch_that_image() {
    global $post, $posts;
    $first_img = '';
    ob_start();
    ob_end_clean();
    $output = preg_match_all('/<img.+?src=[\'"]([^\'"]+)[\'"].*?>/i', $post->post_content, $matches);
    if ($output) {
        $first_img = $matches[1][0];
    }

    if (empty($first_img)) {
        $first_img = bloginfo('template_url') . "/assets/images/default_image.jpeg";
    }
    return $first_img;
}

默认图片:default_image.jpeg,需要自己找一张。

WordPress分页改不了分页URL的问题,并且分页 页面提示“找不到页面”

一个分页问题搞了一晚上和一上午,分页函数`paginate_links`生成的链接一直是`/page/2`这种,并且打不开,提示找不到页面。

google+baidu 几乎找遍了也没找到解决方案。最后在看`paginate_links`参数时,发现第一个参数`base`的意思是”Base of the paginated url”,翻译过来就是“分页URL的基础”,忽然意识到是不是这个参数的原因。

由于之前分页代码是在网上随便找的,`base`参数是

$big = 999999999;
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),

打印了一下它的值是https://notes.wujie.me/case/page/%#%,也就是说生成的分页链接就是/case/page/%#%这种格式的。

那么到此就可以确定是该参数的问题,解决办法就是不使用该参数,或者使用它的默认值%_%,即可把分页URL改成https://notes.wujie.me/case?page=2这种默认样式。

至于为什么只有默认URL样式才能访问,而page/2这样样式会找不到页面,就不得而知了。

最终改过之后的代码如下:

global $wp_query;
echo paginate_links( array(
     'base' => '%_%',
     'format' => '?page=%#%',
     'current' => max( 1, get_query_var('page') ),
     'total' => $wp_query->max_num_pages
 ) );

附一个兼容boostrap4的分页样式:

// 兼容bootstrap4的分页
function bootstrap_pagination(\WP_Query $wp_query = null, $echo = true) {
    if (null === $wp_query) {
        global $wp_query;
    }

    $pages = paginate_links(
        [
            //'base'         => str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ),
            'format'       => '?page=%#%',
            'current'      => max(1, get_query_var('paged')),
            'total'        => $wp_query->max_num_pages,
            'type'         => 'array',
            'show_all'     => false,
            'end_size'     => 3,
            'mid_size'     => 1,
            'prev_next'    => true,
            'prev_text'    => __('« 上一页'),
            'next_text'    => __('下一页 »'),
            'add_args'     => false,
            'add_fragment' => ''
        ]
    );

    if (is_array($pages)) {
        //$paged = ( get_query_var( 'paged' ) == 0 ) ? 1 : get_query_var( 'paged' );
        $pagination = '<div class="pagination"><ul class="pagination">';
        foreach ($pages as $page) {
            $pagination .= '<li class="page-item' . (strpos($page, 'current') !== false ? ' active' : '') . '"> ' . str_replace('page-numbers', 'page-link', $page) . '</li>';
        }
        $pagination .= '</ul></div>';
        if ($echo) {
            echo $pagination;
        } else {
            return $pagination;
        }
    }
    return null;
}

经验教训:复制网上的代码时,要弄懂每一行在干什么,不要随意粘贴到自己的项目中。

WordPress创建自定义文章类型 CPT (custom post type)

注册自定义文章类型,代码如下:

add_action('init', 'my_custom_post_product');
function my_custom_post_product() {
    $labels = array(
        'name'               => _x('产品中心', 'post type 名称'),
        'singular_name'      => _x('产品', 'post type 单个 item 时的名称,因为英文有复数'),
        'add_new'            => _x('添加产品', '添加新内容的链接名称'),
        'add_new_item'       => __('添加新产品'),
        'edit_item'          => __('编辑产品'),
        'new_item'           => __('新产品'),
        'all_items'          => __('产品列表'),
        'view_item'          => __('查看产品'),
        'search_items'       => __('搜索产品'),
        'not_found'          => __('没有找到有关产品'),
        'not_found_in_trash' => __('回收站里面没有相关产品'),
        'parent_item_colon'  => '',
        'menu_name'          => '产品管理'
    );

    $args = array(
        'labels'        => $labels,
        'description'   => '我们网站的产品信息',
        'public'        => true,
        'menu_position' => 5,
        'menu_icon'     => 'dashicons-money-alt',
        // 支持的功能,还可以添加:'excerpt', ,  'comments'
        'supports'      => array('title', 'editor', 'thumbnail'),
        /*这个设置为true,
        才能在前台 single-[post_type].php 和 archive-[post_type].php 显示列表*/
        'has_archive'   => true

    );
    // 注册文章类型,第一个参数为类型名称,即post type name
    register_post_type('product', $args);
}

为新注册的类型,添加分类功能,代码如下:

/**
 * 为产品 post type 添加分类功能
 */
add_action('init', 'my_taxonomies_product', 0);
function my_taxonomies_product() {
    $labels = array(
        'name'              => _x('产品分类', 'taxonomy 名称'),
        'singular_name'     => _x('产品分类', 'taxonomy 单数名称'),
        'search_items'      => __('搜索产品分类'),
        'all_items'         => __('所有产品分类'),
        'parent_item'       => __('该产品分类的上级分类'),
        'parent_item_colon' => __('该产品分类的上级分类:'),
        'edit_item'         => __('编辑产品分类'),
        'update_item'       => __('更新产品分类'),
        'add_new_item'      => __('添加新的产品分类'),
        'new_item_name'     => __('新产品分类'),
        'menu_name'         => __('产品分类'),
    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
    );
    /** 注册分类,第一个参数为分类法的名字,即taxonomy
    第二个参数为该分类属于哪个文章类型 */
    register_taxonomy('product_category', 'product', $args);
}


为新注册的文章类型添加额外的输入框,即 meta box

/**
 * 为产品发布类型 添加自定义 Meta Box
 * 功能特征 meta box
 */
add_action('add_meta_boxes', 'product_gongneng');
function product_gongneng() {
    // add_meta_box( $id, $title, $callback, $post_type, $context,$priority, $callback_args );
    add_meta_box(
        'product_gongneng',                 // id
        '功能特征',                          // title        
        'product_gongneng_meta_box',        // callback
        'product',                          // post_type
        'normal',                           // context
        'low'                               // priority
    );
}

/**
 * 为meta box 添加html表单
 */
function product_gongneng_meta_box($post) {
    // 创建临时隐藏表单,为了安全
    wp_nonce_field('product_gongneng_meta_box', 'product_gongneng_meta_box_nonce');

    // 获取之前存储的值
    $field_value = get_post_meta($post->ID, '_product_gongneng', false);
?>
    <p>
        <label for="_product_gongneng"></label>
        <?php
        $settings = array(
            'quicktags' => array('buttons' => 'em,strong,link',),
            'quicktags' => true,
            'tinymce' => true,
            'editor_height' => 100, // In pixels, takes precedence and has no default value
            'textarea_rows' => 20,  // Has no visible effect if editor_height is set, default is 20
        );

        wp_editor(html_entity_decode($field_value[0]), '_product_gongneng', $settings);
        ?>
    </p>
<?php

}


// 保存meta_box
add_action('save_post', 'product_gongneng_save_meta_box');
function product_gongneng_save_meta_box($post_id) {
    // 安全检查
    // 检查是否发送了一次性隐藏表单内容(判断是否为第三者模拟提交)
    if (!isset($_POST['product_gongneng_meta_box_nonce'])) {
        echo 'a11111';
        exit();
        return;
    }

    // 判断隐藏表单的值与之前是否相同
    if (!wp_verify_nonce($_POST['product_gongneng_meta_box_nonce'], 'product_gongneng_meta_box')) {
        echo '222';
        exit();
        return;
    }

    // 判断该用户是否有权限
    if (!current_user_can('edit_post', $post_id)) {
        echo '333';
        exit();
        return;
    }


    // 判断 Meta Box 是否为空
    if (!isset($_POST['_product_gongneng'])) {
        echo '444';
        exit();
        return;
    }

    // 使用 wpautop 函数,是因为表单中 使用了富文本编辑器,要对文本进行处理
    $gongeng = htmlentities(wpautop($_POST['_product_gongneng']));
    $_product_gongneng = sanitize_text_field($gongeng);
    // 把字段值保存到数据库
    update_post_meta($post_id, '_product_gongneng', $_product_gongneng);
}

查看Debian开机启动项

查看所有启用的服务:

systemctl list-unit-files --type=service

该命令会列出所有服务的启动状态,其中标记为 enabled 的服务会在开机时自动启动。

查看当前正在运行的服务:

systemctl list-units --type=service

这个命令会列出当前正在运行的服务,已启动的服务会标记为 running。

systemctl list-unit-files --type=service 输出 列表太长,如果不想看整个列表,只想简单地查看启用的服务,可以运行以下命令:

systemctl list-unit-files --type=service | grep enabled

这个命令会列出所有启用(enabled)的服务,只有那些会在系统启动时自动启动的服务会被显示。

查看当前运行的服务

systemctl list-units --type=service --state=running

这个命令会显示当前正在运行的服务,但它不会直接列出所有已配置为开机启动的服务。它只会列出系统启动后当前处于运行状态的服务。

检查特定服务是否设置为开机启动

systemctl is-enabled <service-name>

例如,要查看 ssh 服务是否在开机时启动:

systemctl is-enabled ssh

如果返回 enabled,则表示该服务已配置为开机启动。

使用 grep 筛选开机启动的服务(更简洁的命令)

systemctl list-unit-files --type=service | awk '$2=="enabled" {print $1}'

这个命令会只输出那些标记为 enabled 的服务名称,避免显示其他无关的服务信息。

最后,也可以查看/etc/init.d/目录(SysVinit 脚本,这个适合于老旧的系统,新系统中也会有这个目录,但不太推荐使用了)

ls /etc/init.d/