PIX主题添加注册弹窗功能,把PIX从单用户朋友圈博客变为多用户互动博客
本文是《技术相关(共39篇)》目录的第 12 篇。阅读本文前,建议先阅读本文前3篇文章:
PIX主题本身是一个类似于朋友圈的单用户博客,尽管基于wordpress开发,但是没有注册入口。这么好的主题,尤其是卡片动态功能,如果只是站长一个人发,太没有意思了,赶紧上车,让我们改进PIX主题,添加一个注册弹窗功能。
本文修改后需要更新缓存。为保证安全,新注册用户一律为订阅者,订阅者只有评论文章功能,后台需要编辑用户资料改为投稿者(贡献者)或者作者才能发布片刻和文章,前者需要审核才能显示,并且不能删除自己发布的内容,后者无需审核,并且对于仅限自己发布的内容拥有完全的权限。站长可以根据实际情况进行权限分配。
一、实现原理和逻辑:
在保持现有登录弹窗代码及功能不变的前提下,新增一个注册弹窗,能够通过点击文字实现相互左右翻转切换。
注册弹窗有三个注册时必须输入的地方:用户名、密码和邮箱。注册后不会发注册邮件,将直接返回进行登录。新注册用户默认角色为订阅者。
同一个用户名或者邮件只能被注册一次,密码必须时数字和字母结合且长度不小于8位,如果三者未输入或不满足注册条件,则进行相应提示。
未输入提示:
用户名已被注册提示:
邮箱已被注册提示:
用户名和邮箱同时被注册提示:
密码不符合要求提示:
二、修改文件:
1、修改pix/layouts/login-form.php,用以下代码代替:
[reply]
<?php
$wp_load_path = $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php';
require_once($wp_load_path);
// Check if the form is submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Get the form data
$username = sanitize_user($_POST['username']);
$password = $_POST['password'];
$email = sanitize_email($_POST['user_email']);
// Initialize error message
$error_message = '';
// Check if all required fields are filled
if (empty($username) || empty($password) || empty($email)) {
// Set error message for missing fields
$error_message = '用户名、邮箱和密码必须全部填写!';
} else {
// Check if the email address is already registered
$email_exists = email_exists($email);
if ($email_exists) {
// Set error message for existing email
$error_message = '该邮箱已被注册,请更换邮箱!';
}
// Check if the username is already taken
$username_exists = username_exists($username);
if ($username_exists) {
// Set error message for existing username
$error_message = '该用户名已被注册,请更换用户名!';
}
$email_exists = email_exists($email);
$username_exists = username_exists($username);
if ($email_exists && $username_exists) {
// Set error message for existing email and username
$error_message = '该用户名和该邮箱均已被注册,请更换用户名和邮箱!';
}
// Check if the password meets the requirements (at least two character types)
$password_valid = preg_match('/^(?=.*\d)(?=.*[a-zA-Z]).{8,}$/', $password);
if (!$password_valid) {
// Set error message for invalid password
$error_message = '请检查密码是否包含至少一个数字和一个字母,并且长度至少为8个字符!';
}
}
// Send the response as JSON
$response = array();
if (!empty($error_message)) {
$response['success'] = false;
$response['message'] = $error_message;
} else {
// Create a new user
$user_id = wp_create_user($username, $password, $email);
if (!is_wp_error($user_id)) {
// Set the user role to "subscriber"
$user = new WP_User($user_id);
$user->set_role('subscriber');
$response['success'] = true;
$response['message'] = '注册本站成功,请您登录!';
}
}
// Send the JSON response
header('Content-Type: application/json');
echo json_encode($response);
exit;
}
?>
<style>
.flip_text span {
font-size: 12px;
}
.flip_text span#register_text,
.flip_text span#login_text {
color: blue;
cursor: pointer;
text-decoration: none;
}
</style>
<div id="login_form_box" uk-modal>
<div class="modal_inner uk-modal-dialog uk-modal-body round8 uk-margin-auto-vertical">
<button class="uk-modal-close-outside" type="button" uk-close></button>
<div class="front">
<form id="login" class="ajax-auth log" action="login" method="post">
<p class="log_title">登录 | SIGN IN</p>
<?php echo wp_nonce_field('ajax-login-nonce', 'security', true, false); ?>
<label for="username">
<i class="ri-user-4-line"></i>
<input id="username" type="text" class="required" name="username" placeholder="用户名">
</label>
<label for="password">
<i class="ri-lock-line"></i>
<input id="password" type="password" class="required" name="password" placeholder="密码">
</label>
<input class="submit_button" type="submit" value="登录">
<p class="flip_text">
<span class="account_text">还没有账号?</span>
<span id="register_text" class="action_text">点击注册</span>
</p>
</form>
</div>
<div class="back" style="display: none;">
<form id="register" class="ajax-auth log" action="<?php echo get_template_directory_uri() . '/layouts/login-form.php'; ?>" method="post">
<p class="log_title">注册 | SIGN UP</p>
<?php echo wp_nonce_field('ajax-register-nonce', 'security', true, false); ?>
<label for="reg_username">
<i class="ri-user-4-line"></i>
<input id="reg_username" type="text" class="required" name="username" placeholder="用户名">
</label>
<label for="reg_password">
<i class="ri-lock-line"></i>
<input id="reg_password" type="password" class="required" name="password" placeholder="密码">
</label>
<label for="reg_email">
<i class="ri-mail-line"></i>
<input id="reg_email" type="email" class="required" name="user_email" placeholder="邮箱">
</label>
<input type="hidden" name="no_password_reset" value="1"> <!-- Add this line to disable password reset -->
<input class="submit_button" type="submit" value="注册">
<p class="flip_text">
<span class="account_text">已有账号?</span>
<span id="login_text" class="action_text">点击登录</span>
</p>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
var frontForm = document.querySelector('.front');
var backForm = document.querySelector('.back');
var flipToRegister = function () {
frontForm.style.display = 'none';
backForm.style.display = 'block';
};
var flipToLogin = function () {
frontForm.style.display = 'block';
backForm.style.display = 'none';
};
var registerText = document.getElementById('register_text');
registerText.addEventListener('click', flipToRegister);
var loginText = document.getElementById('login_text');
loginText.addEventListener('click', flipToLogin);
var closeButton = document.querySelector('.uk-modal-close-outside');
closeButton.style.right = '0';
closeButton.style.top = '0';
var registerForm = document.getElementById('register');
registerForm.addEventListener('submit', function (event) {
event.preventDefault(); // Prevent form submission
// 清除之前的错误消息
var errorDivs = document.querySelectorAll('.modal_inner > div');
for (var i = 0; i < errorDivs.length; i++) {
var errorDiv = errorDivs[i];
if (errorDiv.style.color === 'red') {
errorDiv.remove();
}
}
// Get form data
var formData = new FormData(registerForm);
// Send the form data using Ajax
var xhr = new XMLHttpRequest();
xhr.open('POST', '<?php echo get_template_directory_uri() . '/layouts/login-form.php'; ?>', true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onload = function () {
if (xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
if (response.success) {
// Display success message
var successDiv = document.createElement('div');
successDiv.innerHTML = response.message;
successDiv.style.color = 'green';
successDiv.style.fontSize = '12px';
successDiv.style.textAlign = 'center';
var modalInner = document.querySelector('.modal_inner');
modalInner.insertBefore(successDiv, modalInner.firstChild);
// Close the modal after 3 seconds
setTimeout(function () {
document.querySelector('.uk-modal-close-outside').click();
}, 3000);
} else {
// Display error message
var errorDiv = document.createElement('div');
errorDiv.innerHTML = response.message;
errorDiv.style.color = 'red';
errorDiv.style.fontSize = '12px';
errorDiv.style.textAlign = 'center';
var modalInner = document.querySelector('.modal_inner');
modalInner.insertBefore(errorDiv, modalInner.firstChild);
}
}
};
xhr.send(formData);
});
});
</script>
[/reply]
2、修改pix/inc/assets/css/main.css,大概3310-3368行,或者搜索
#login_form_box .modal_inner {
width: 280px;
}
开始,
#login_form_box label i {
position: absolute;
left: 10px;
color: #6c8677;
}
结束。
将以上代码包含开始和结束替换为:
#login_form_box .modal_inner {
width: 280px;
}
form#login label {
position: relative;
display: flex;
margin-bottom: 10px;
align-items: center;
justify-content: flex-start;
align-content: center;
}
form#register label {
position: relative;
display: flex;
margin-bottom: 10px;
align-items: center;
justify-content: flex-start;
align-content: center;
}
#login_form_box input#reg_username,
#login_form_box input#reg_password,
#login_form_box input#reg_email {
width: 100%;
font-size: 13px;
padding: 8px 5px 8px 40px;
background: #ebf2ed;
border-color: #c2cfc9;
outline: none;
border-radius: 8px;
}
#login_form_box input#reg_username:focus,
#login_form_box input#reg_password:focus,
#login_form_box input#reg_email:focus {
border-color: #00bb5e;
}
#login_form_box input#username , #login_form_box input#password {
width: 100%;
font-size: 13px;
padding: 8px 5px 8px 40px;
background: #ebf2ed;
border-color: #c2cfc9;
outline: none;
border-radius: 8px;
}
#login_form_box input#username:focus , #login_form_box input#password:focus {
border-color: #00bb5e;
}
#login_form_box label i {
position: absolute;
left: 10px;
color: #6c8677;
}
3、修改pix/inc/pix-fn.php前两个函数,以实现不同发布者获取不同的头像和昵称,即以下两个函数:
//获取头像 function get_user_avatar()
//获取昵称 function get_nickname()
修改后代码如下:
[reply]
//获取头像
function get_user_avatar() {
global $post;
$de_img = THEME_URL . '/img/avatar.png';
$img = '<img src="' . $de_img . '">';
if (isset($post)) {
$author_id = $post->post_author;
if (in_array('administrator', get_userdata($author_id)->roles)) {
$type = get_op('avatar_type');
if ($type == 'email') {
$email = get_userdata($author_id)->user_email;
$img = get_avatar($email, '100');
} else if ($type == 'custom') {
$img = '<img src="' . get_op('default_avatar') . '">';
}
} else {
$img = get_avatar($author_id, '100');
}
}
return $img;
}
//获取昵称
function get_nickname() {
global $post;
$user = wp_get_current_user();
if (isset($post) && ($post->post_author == $user->ID)) {
// Current user is the author of the post/moment/comment
if (in_array('administrator', $user->roles)) {
$nice_name = get_op('nice_name');
if ($nice_name) {
$name = $nice_name;
} else {
$name = $user->display_name;
}
} else {
$name = $user->display_name;
}
} else {
// Current user is not the author of the post/moment/comment
if (isset($post)) {
$author = get_user_by('id', $post->post_author);
if (in_array('administrator', $author->roles)) {
$nice_name = get_op('nice_name');
if ($nice_name) {
$name = $nice_name;
} else {
$name = $author->display_name;
}
} else {
$name = $author->display_name;
}
} else {
$name = $user->display_name;
}
}
return $name;
}
[/reply]
实现的逻辑:判断已经发布的片刻moment、文章post或者评论comment的发布者身份,如果是管理员,优先显示后台“常规设置---博主自定义昵称”作为昵称,如果后台”常规设置---博主自定义昵称“没有填写,则显示后台”个人资料---公开显示为“作为昵称;如果不是管理员,直接显示后台”个人资料---公开显示为“作为昵称;头像取各自的头像。
4、修改pix/layouts/header-tool.php,使右上角头像也能正确获取当前登录用户的正确头像。
[reply]
<div class="top_right">
<?php echo msg_btn(); ?>
<?php if(is_user_logged_in()){ ?>
<div class="t_login top_tool icon_color">
<a class="normal_edit" uk-toggle="target: #create_post_box"><i class="ri-edit-box-line"></i></a>
</div>
<div class="admin_ava">
<a class="mobile_edit" uk-toggle="target: #create_post_box"><i class="ri-add-line"></i></a>
<div class="top_ava"><?php echo get_avatar(get_current_user_id(), 64, get_option('avatar_default')); ?></div>
<div class="user_pannel round12" uk-dropdown="mode: click;toggle:.top_ava;pos:bottom-right;animation:uk-animation-slide-top-small">
<div class="inner">
<a href="<?php echo home_url('/wp-admin'); ?>" target="_blank" pjax="exclude"><i class="ri-function-line"></i>控制台</a>
<?php
if (is_user_logged_in()) {
$current_user = wp_get_current_user();
$author_url = home_url('/author/') . $current_user->user_login;
?>
<a href="<?php echo $author_url; ?>"><i class="ri-user-3-fill"></i>我的主页</a>
<?php } ?>
<a href="<?php echo wp_logout_url(cst_get_curl()); ?>" pjax="exclude"><i class="ri-logout-circle-r-line"></i>登出</a>
</div>
</div>
</div>
<?php } else { ?>
<div class="top_tool">
<a uk-toggle="target: #login_form_box"><i class="ri-user-4-fill"></i></a>
</div>
<?php } ?>
</div>
[/reply]
5、修改pix/tpl/content-moment.php,实现非管理员用户前台可以直接编辑片刻moment,但非管理员用户不能置顶片刻,如需置顶,需要向管理员申请。申请通过即全局全站置顶,并在片刻右上角编辑功能下方显示置顶专用图标。
因为只有注册用户才能发布片刻,因此,点击用户名会进入相应的用户作者主页中,鼠标放上去的时候,会提示:“进入XXX的作者主页”。
代码修改如下:
[reply]
<?php
/**
* Template part for displaying posts
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package pix
*/
$loca = get_post_meta(get_the_ID(), 'mylocal',true);
$local_h = '';
if(strlen(trim($loca)) > 2){
$local_h = '<i class="ri-map-pin-2-line"></i>'.$loca.'';
} else {
$local_h = '';
}
$post_ID = get_the_ID();
$comment_off = get_op('com_close') ? get_op('com_close') :false;
$m_sticky = is_sticky() ? 'unstick' : 'stick';
$m_sticky_text = is_sticky() ? '取消置顶' : '置顶片刻';
$current_user_id = get_current_user_id();
$post_author_id = get_post_field('post_author', $post_ID);
$is_admin = current_user_can('manage_options');
?>
<div id="post-<?php the_ID(); ?>" <?php post_class('loop_content p_item moment_item uk-animation-slide-bottom-small'); ?>>
<div class="p_item_inner">
<?php if(($current_user_id == $post_author_id && !$is_admin) || $is_admin) { ?>
<div class="post_control">
<a class="post_control_btn"><i class="ri-menu-3-line"></i></a>
<div class="post_control_box">
<div class="post_control_list round8 shadow uk-animation-slide-bottom-small uk-animation-fast" pid="<?php echo $post_ID ?>">
<a class="control_edit_post control_type" uk-toggle="target: #create_post_box">编辑片刻</a>
<?php if ($is_admin) { ?>
<a class="<?php echo $m_sticky ?> control_type sticky_btn"><?php echo $m_sticky_text ?></a>
<?php } ?>
<a class="control_delete_post control_type">删除片刻</a>
</div>
</div>
</div>
<?php } ?>
<div class="list_user_meta">
<div class="avatar"><?php echo get_user_avatar(); ?></div>
<div class="name">
<a href="<?php echo home_url('/author/' . get_the_author_meta('user_nicename')); ?>" title="进入<?php echo get_nickname(); ?>的作者主页"><?php echo get_nickname(); ?></a>
<time itemprop="datePublished" datetime="<?php echo get_the_date('c');?>"><?php echo ''.timeago( get_gmt_from_date(get_the_time('Y-m-d G:i:s')) ); ?></time>
</div>
</div>
<div class="blog_content">
<div class="sticky_icon_wrap" style="position: relative;">
<?php if (is_sticky()) { ?>
<img class="sticky_icon" src="https://my1981.cn/wp-content/themes/pix/img/zhiding.png" alt="置顶图标" style="position: absolute; right: 0; width: 60px; height: 60px;">
<?php } ?>
</div>
<div class="entry-content">
<div class="p_title"><a href="<?php echo get_permalink();?>"><?php the_title('<i class="ri-at-line"></i>',''); ?></a></div>
<div class="t_content"><p><?php echo moment_excerpt(); ?></p></div>
<?php echo get_moment_type_content(); ?>
</div><!-- .entry-content -->
<span class="ip_loca"><?php echo $local_h ?></span>
<div class="entry-footer">
<div class="post_footer_meta">
<div class="left">
<?php echo get_like_btn(); ?>
<?php echo share_btn(); ?>
</div>
<div class="right">
<?php if(is_sticky()){ echo '<span class="sticky_icon"><i class="ri-fire-line"></i> TOP</span>';} ?>
<?php if($comment_off !=true){ ?>
<span class="comnum show_comment" pid="<?php echo get_the_ID(); ?>"><i class="ri-message-3-line"></i><?php echo get_comments_number(); ?></span>
<?php } ?>
</div>
</div>
</div><!-- .entry-footer -->
<div class="topic_comments_wrap t_com_<?php echo $post_ID; ?>" style="display:none">
<?php
global $withcomments;
$withcomments = true;
comments_template('/layouts/topic-comments.php');
?>
</div>
</div>
</div>
</div><!-- #post-<?php the_ID(); ?> -->
[/reply]
6、修改pix/tpl/single-moment.php,添加置顶图标和作者主页,与content-moment.php保持一致。
[reply]
<?php
/**
* Template part for displaying posts
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package pix
*/
$loca = get_post_meta(get_the_ID(), 'mylocal',true);
$local_h = '';
if(strlen(trim($loca)) > 2){
$local_h = '<i class="ri-map-pin-2-line"></i>'.$loca.'';
} else {
$local_h = '';
}
$post_ID = get_the_ID();
?>
<div id="post-<?php the_ID(); ?>" <?php post_class('loop_content p_item moment_item moment_single'); ?>>
<div class="p_item_inner">
<div class="list_user_meta">
<div class="avatar"><?php echo get_user_avatar(); ?></div>
<div class="name">
<a href="<?php echo home_url('/author/' . get_the_author_meta('user_nicename')); ?>" title="进入<?php echo get_nickname(); ?>的作者主页"><?php echo get_nickname(); ?></a>
<time itemprop="datePublished" datetime="<?php echo get_the_date('c');?>"><?php echo ''.timeago( get_gmt_from_date(get_the_time('Y-m-d G:i:s')) ); ?></time>
</div>
</div>
<div class="blog_content">
<div class="sticky_icon_wrap" style="position: relative;">
<?php if (is_sticky()) { ?>
<img class="sticky_icon" src="https://my1981.cn/wp-content/themes/pix/img/zhiding.png" alt="置顶图标" style="position: absolute; right: 0; width: 60px; height: 60px;">
<?php } ?>
</div>
<div class="entry-content">
<div class="p_title"><?php the_title('<i class="ri-at-line"></i>',''); ?>
<?php if (is_sticky()) { ?>
<img class="sticky_icon" src="https://my1981.cn/wp-content/themes/pix/img/zhiding.png" alt="置顶图标" style="position: absolute; right: 0; width: 30px; height: 30px;">
<?php } ?>
</div>
<div class="t_content"><p><?php echo get_the_content(); ?></p></div>
<?php echo get_moment_type_content(); ?>
</div><!-- .entry-content -->
<span class="ip_loca"><?php echo $local_h ?></span>
<div class="entry-footer">
<div class="post_footer_meta">
<div class="left">
<?php echo get_like_btn(); ?>
<?php echo share_btn(); ?>
</div>
<div class="right" pid="<?php echo $post_ID ?>">
<?php if (current_user_can( 'edit_post', $post_ID ) || current_user_can( 'manage_options') ) { ?>
<a class="control_edit_post control_type" uk-toggle="target: #create_post_box"><i class="ri-edit-line"></i>编辑</a>
<?php } ?>
</div>
</div>
</div><!-- .entry-footer -->
</div>
</div>
</div><!-- #post-<?php the_ID(); ?> -->
[/reply]
7、非必须修改项一:如果参照本站使用了回复显示功能,原来的代码需要修改,以上改完后,注册会员无需回复即可查看隐藏内容,需要修改成回复查看。
原来的帖子内容参见本文:
修改后代码如下,文件位置参照上文。
[reply]
function reply_to_read($atts, $content=null) {
extract(shortcode_atts(array(
"notice" => '<div class="reply-to-read"><p><font color="#ff0000">温馨提示: </font>此处为隐藏内容,需要<a href="#respond" title="评论本文">评论本文</a>后才能查看.<br><font size="2"><b>评论后请刷新一次页面,但注意不要清除缓存,否则还需要再次评论!</b></font></p></div>'
), $atts));
$user = wp_get_current_user();
$user_id = $user->ID;
// 检查当前用户角色
if (in_array('administrator', $user->roles)) {
// 如果是管理员,直接显示内容
return $content;
} else {
// 如果是普通用户
if ($user_id > 0) {
// 如果用户已登录,检查是否回复过
global $wpdb;
$post_id = get_the_ID();
$query = "SELECT `comment_ID` FROM {$wpdb->comments} WHERE `comment_post_ID`={$post_id} AND `user_id`={$user_id} LIMIT 1";
if ($wpdb->get_results($query)) {
// 如果用户已回复过,显示内容
return do_shortcode($content);
}
} else {
// 如果用户未登录,检查是否有评论者的 cookie
if (isset($_COOKIE['comment_author_email_' . COOKIEHASH])) {
// 如果有评论者的 cookie,显示内容
return do_shortcode($content);
}
}
// 用户未回复或未登录,显示提示内容
return $notice;
}
}
add_shortcode('reply', 'reply_to_read');
[/reply]
8、非必须修改项二:如果在评论时提示错误,因为现在我的又不提示错误了,忘记具体提示内容了,但是错误是指向wp-includes/comment-template.php第一段函数,则第一段函数修改为:
function get_comment_author( $comment_id = 0 ) {
$comment = get_comment( $comment_id );
$comment_id = ! empty( $comment->comment_ID ) ? $comment->comment_ID : $comment_id;
if ( empty( $comment->comment_author ) ) {
$user = ! empty( $comment->user_id ) ? get_userdata( $comment->user_id ) : false;
if ( $user ) {
$comment_author = $user->display_name;
} else {
$comment_author = __( 'Anonymous' );
}
} else {
$comment_author = $comment->comment_author;
}
更新缓存,大功告成!
您已阅读完《技术相关(共39篇)》目录的第 12 篇。请继续阅读本文后3篇文章:
战东海
这回网站能刷新出来来
似水流年
是的。
sanant
看下评论。
opopo
评论隐藏不显示呢!!!
似水流年
刷新下页面。
740080298@qq.com
没用,刷新也不出来~~~😃
似水流年
稍等,我看下。
似水流年
重新刷新一下,或者重新评论一下再刷新试试,应该可以了。
740080298@qq.com
看看隐藏
似水流年
刷新下页面。