wp

WordPress — 世界上最快速的建站平台, 优点:

  • 历史悠久,故拥有最丰富的插件市场
  • 后台管理功能丰富. 配合插件,几乎可以实现任何功能
  • 适合普罗大众, 无需任何编码知识便能构建自己的网站

缺点也同样显著:

  • 速度慢 — 归功于PHP ➡️ 世界上最好的语言
  • 漏洞多 — 同上
  • 传言Facebook的官网既是针对PHP做的定制开发 — 看来他们是真爱 💕

https://wordpress.org/download/

wget https://wordpress.org/latest.tar.gz
groupadd www
useradd www -s /sbin/nologin -g www -M  # M:no create home
chown -R www:www /home/www

basic

  • xx/wp-admin: 默认admin-dashboard
  • 设置 - 固定链接: 最好不要设置为朴素,后续麻烦多.一般搞成数字型!
  • 用户信息uri: /archives/author/<username>
  • 注意: db的备份恢复不要使用工具. 使用命令行!! 参考db章节!!
  • 注意: 使用简单密码的修改操作貌似是不成功的,也不会告诉你不成功!
  • 注意: 网站出现错误访问不了怎么办? vim wp-config.php WP_DEBUG true

Terminology

  • page: 静态页面(一般放在导航栏上),有层级的概念,可按层排序.一般做网站都是先列出结构(Home+About+Products+ContactUs+..).然后对应的创建各个框架页面!
  • post: 内容或文章(以时间顺序排列).有分类和标签的概念(比如属于技术类还是娱乐类).
  • menu: 一般是根据上面两者来创建.通过拖动完成.当然也可以自己添加,指定链接.
  • 小工具: 博客中右边的分类小块.也可以定制footer.
  • 多媒体: 写文章时可能会用到的一些图片等资源.
  • 编辑: Editor.还可以添加/管理页面等操作.
  • 作者: Author.无需管理员审核,可添加/编辑/删除文章,上传文件.
  • 投稿者: Contributor.只能编辑/删除自己的文章.不能添加文章(没啥用)!比订阅者Subscriber权限大一点.

https

  • [设置] - [常规]: 俩个都改成https
  • wp-config.php
    define('FORCE_SSL_LOGIN', true);
    define('FORCE_SSL_ADMIN', true);
  • nginx: 80全部转发到443
    rewrite ^(.*)$ https://$host$1 permanent;

configs

define('DISABLE_WP_CRON', true);  // 提高效率
define('DISALLOW_FILE_EDIT', true);
vim wp-content/uploads/.htaccess
# <Files *.php>
# deny from all
# </Files>
vim .htaccess
# <Files xmlrpc.php>
# order deny,allow
# deny from all
# allow from 127.0.0.1
# </Files>

functions.php

// Start Restrict API acess to localhost
function restrict_rest_api_to_localhost() {
    $whitelist = ['127.0.0.1', '::1'];

    if (!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
        //die( 'REST API is not available.' );
        new WP_Error('forbidden_access', 'Access denied', array('status' => 403));
    }
}
add_action('rest_api_init', 'restrict_rest_api_to_localhost', 0);

plugins

https://github.com/dchijack/wp-mini-program

  • 注意: 不要安装官网上的memcached插件!具体安装方法参见PHP章节
  • 注意: wordfence卸载后要一起删除根目录下的 .user.ini
PluginFunction
DisableGutenberg经典编辑器; Advanced Editor Tools; Enlighter!
404page定制404页面.
wps hide login安全插件.伪静态nginx设置无需: rewrite /wp-admin$ $scheme://$host$uri/ permanent;
Login LockDown登录锁定
Captcha Code增加验证码环节
WP Optimize优化
WP Mail SMTP注册新用户使用的是邮箱,密码通过邮件发送.wp默认发送邮件功能被屏蔽了!
WP-PgeNavi更高级的分页导航,不仅仅是前一页后一页,还增加'1 2 3’等定位页!
Enable Media Replace原始的删除+上传+重命名太繁琐!
Login Designer登录页面美化
Mediamatic媒体库分类
JWT Authentication支持’REST API’JWT校验登录
StarBox用户信息
Login to view all设置page部分内容登录才可见(注意:在网站迁移的时候有问题,需要在前一千删除之!)
WP Baidu Maps需要去百度地图开发平台创建应用(类别:浏览器端,referer不要使用*,写xx.xx)获取ak,然后: vim wp-baidu-map.php; 修改myaks
WP User Avatar支持新用户修改编辑头像
Elementor页面编辑
Useso take over Google替换谷歌字体
Wordfence安全插件! AllInOne这个与REST-API+JWT有兼容性问题! 注意:防火墙中的’防止通过/?author=…‘也要取消勾选,否则REST-API获取用户信息时会受到屏蔽!
WP Editor.md不好用,会屏蔽经典编辑器
page order调整page的顺序;
Favorites文章搜藏 bk:#fb8c1f 已收藏:bk:#f5f5f5,fg:#c2c2c2
WX Custom Share微信分享
WeChat Subscribers Lite公众号同步
Elementor Page Builder页面设计
QQWorld Auto Save Images文章中图片自动保存
WooCommerce电商插件
Alipay For WooCommerce支持支付宝
WooCommerce Checkout Field Editor编辑表单字段
Ultimate Member终极会员(注意:安装完成后需要汉化一些表格,尤其注意要设置用户角色的权限,不然非订阅者不可以编辑!!)
Nav Menu Roles控制菜单项的可见性
Remove Dashboard控制哪些角色可以访问控制台,以及登录重定向的URL.
Easy FancyBox图片弹框
Author Avatars List用户列表
category order调整博客侧边分类边栏中,各个分类的顺序.
delete revisionwp默认自带文章的版本历史,方便回退.此插件可批量上传修订.
revision control控制修订版本的个数.
Responsive Lightbox&Gallery拖拽便捷组件
WP Super Cache网站缓存,加速
Disable Comments禁用所有评论
No Self Pings禁用评论中的Pingbacks

Theme Customize

移除左上角的W标志菜单

vim wp-includes/class-wp-admin-bar.php 注释掉: wp_admin_bar_wp_menu

theme汉化

  • 文章By: wp-content/themes/hueman/parts/single-author-date.php
  • 页脚版权: wp-content/themes/hueman/footer.php +121
  • 上下一条汉化: wp-content/themes/hueman/parts/post-nav.php
  • 推荐文章汉化: wp-content/themes/hueman/parts/related-posts.php +20
  • StarBox汉化: wp-content/plugins/starbox/models/Frontend.php +65
    注意 see all也需要改
  • 搜藏汉化: wp-content/plugins/favorites/app/Config/SettingsRepository.php +400 apply_filters
  • 去掉账单详情: wp-content/plugins/woocommerce/templates/checkout/form-billing.php:28 删掉:
    <h3><?php esc_html_e( 'Billing details', 'woocommerce' ); ?></h3>

Miscellaneous

pay: https://blog.csdn.net/qq_38140033/article/details/102371010

  • 用户注册通知邮件里面的设置密码地址错误
    全局搜索: wp-login.php?action=rp&key=<>\r\n等追加字符串全部删掉
    wp-includes/pluggable.php+2005行的 $message.=wp_login_url().. 注释
  • 文件上传大小限制:
    php.ini
    upload_max_filesize + post_max_size
  • wp-config.php
    重装时需要删除,且需要清空db! define('WPLANG', 'zh_CN') –> 回到dashboard,点击updates.更新语言!

REST API

https://developer.wordpress.org/rest-api/

curl -X GET yousite.com/wp-json/wp/v2/posts

注意: 设置-固定连接: 必须改成数字型

.htaccess

  RewriteEngine on
  RewriteCond %{HTTP:Authorization} ^(.*)
  RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
  SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

wp-config.php

注意 要放在 NONCE_SALT 后面,要确保在 ABSPATH 定义之前!

https://api.wordpress.org/secret-key/1.1/salt/

  define('JWT_AUTH_SECRET_KEY', 'your-top-secrect-key');
  define('JWT_AUTH_CORS_ENABLE', true);

request token

POST https://sleepreading.top/wp-json/jwt-auth/v1/token
Content-Type: application/json
{
  "username": "",  // 只要是一个系统注册的用户皆可!
  "password": ""
}
{// ok
  "token": "",  // 每调用一次都会产生一个新的!
  "user_email": "",
  "user_nickname": "",
  "user_display_name": ""
}
{// fail
  "code": "[jwt_auth] incorrect_password/invalid_username/empty_username",
  "message": "",
  "data": {
    "status": 403
  }
}

common request

可以获得该用户对应的private的post

不加Authorization会显示rest_no_route

POST https://sleepreading.top/wp-json/v2/users/me
Content-Type: application/json
Authorization: Bearer xxxx

自定义路径

wp-json; 注意:必须点击设置-固定连接中的保存,重启php-fpm也不行

wp-includes/functions.php

add_filter('rest_url_prefix', function(){
  return 'wp-api';
});
# 未登陆用户禁止使用REST-API
add_filter('rest_authentication_errors', function($result) {
  if (!empty($result)) {
    return $result;
  }
  $whitelist = [
    '/api/jwt-auth/v1/token'
  ];
  if (in_array($_SERVER['REQUEST_URI'], $whitelist)) {
    return true;
  }
  if (!is_user_logged_in()) {
    return new WP_Error('rest_not_logged_in', 'You are not currently logged in.', array('status' => 401));
  }
  return $result;
});

DB

create table `wp_users` (
  `ID` bigint(20) unsigned not null auto_increment,  -- 用户id
  `user_login` varchar(60) not null default '',  -- 用户登录名称
  `user_pass` varchar(255) not null default '',  -- 用户登录密码
  `user_nicename` varchar(50) not null default '',  -- 用户昵称,默认 == user_login
  `user_email `varchar(100) not null default '',
  `user_url` varchar(100) not null default '',
  `user_registered` datetime not null default '0000-00-00 00:00:00',  -- 用户注册时间
  `user_activation_key` varchar(255) not null default '',  -- 用户激活码.重设密码时会使用来对比.
  `user_status` int(11) not null default '0',  -- 用户状态
  `display_name` varchar(250) not null default '',  -- 用户显示名称
  primary key (`ID`),
  key `user_login_key` (`user_login`),
  key `user_nicename` (`user_nicename`),
  key `user_email` (`user_email`)
) engine=InnoDB auto_increment=9 default charset=utf8mb4 collate=utf8mb4_unicode_ci;

create table `wp_posts` (
  `ID` bigint(20) unsigned not null auto_increment,
  `post_author` bigint(20) unsigned not null default '0',  -- 作者uid
  `post_date` datetime not null default '0000-00-00 00:00:00',
  `post_date_gmt` datetime not null default '0000-00-00 00:00:00',
  `post_content` longtext not null,
  `post_title` text not null,
  `post_excerpt` text not null,  -- 摘录
  `post_status` varchar(20) not null default 'publish',  -- auto-draft inherit
  `comment_status` varchar(20) not null default 'open',  -- closed. 评论状态
  `ping_status` varchar(20) not null default 'open',
  `post_password` varchar(255) not null default '',  -- 文章密码
  `post_name` varchar(200) not null default '',  -- 文章缩略名
  `to_ping` text not null,
  `pinged` text not null,
  `post_modified` datetime not null default '0000-00-00 00:00:00',  -- 修改时间
  `post_modified_gmt` datetime not null default '0000-00-00 00:00:00',
  `post_content_filtered` longtext not null,
  `post_parent` bigint(20) not null default '0',
  `guid` varchar(255) not null default '',
  `menu_order` int(11) not null default '0',
  `post_type` varchar(20) not null default 'post',  -- 文章类型: page
  `post_mime_type` varchar(100) not null default '',
  `comment_count` bigint(20) not null default '0',
  primary key (`ID`),
  key `post_name` (`post_name`(191)),
  key `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`),
  key `post_parent` (`post_parent`),
  key `post_author` (`post_author`)
) engine=InnoDB auto_increment=973 default charset=utf8mb4 collate=utf8mb4_unicode_ci;

create table `wp_comments` (
  `comment_ID` bigint(20) unsigned not null auto_increment,
  `comment_post_ID` bigint(20) unsigned not null default '0',  -- 对应文章id
  `comment_author` tinytext not null,  -- 评论者
  `comment_author_email` varchar(100) not null default '',  -- 评论者邮箱
  `comment_author_url` varchar(200) not null default '',
  `comment_author_IP` varchar(100) not null default '',
  `comment_date` datetime not null default '0000-00-00 00:00:00',
  `comment_date_gmt` datetime not null default '0000-00-00 00:00:00',
  `comment_content` text not null,
  `comment_karma` int(11) not null default '0',
  `comment_approved` varchar(20) not null default '1',  -- 评论是否被批准
  `comment_agent` varchar(255) not null default '',
  `comment_type` varchar(20) not null default 'comment',  -- pingback/普通
  `comment_parent` bigint(20) unsigned not null default '0',  -- 父评论id
  `user_id` bigint(20) unsigned not null default '0',  -- 评论者uid,未登录用户则为0
  primary key (`comment_ID`),
  key `comment_post_ID` (`comment_post_ID`),
  key `comment_approved_date_gmt` (`comment_approved`,`comment_date_gmt`),
  key `comment_date_gmt` (`comment_date_gmt`),
  key `comment_parent` (`comment_parent`),
  key `comment_author_email` (`comment_author_email`(10)),
  key `woo_idx_comment_type` (`comment_type`)
) engine=InnoDB auto_increment=6 default charset=utf8mb4 collate=utf8mb4_unicode_ci;