Login, Signup, kiểm tra tình trạng đăng nhập

Tiếp nối với bài về Header thì chúng ta sẽ bàn đến nút Login / Signup có trên Header. Thường thì các flow phổ biến sẽ là:

  • click nút Login / Signup sẽ dẫn sang trang Login, ở đó sẽ có nút dẫn sang trang Signup nếu chưa có tài khoản, hoặc có design sẽ gộp vào 1 trang luôn.

  • sau khi đăng nhập xong, trên header sẽ không hiện nút Login / Signup nữa mà sẽ hiện tên + avatar của user vừa đăng nhập.

  • khi reload thường sẽ giữ trạng thái đăng nhập

  • sẽ có thêm 1 số nút chức năng như nút Logout, hoặc hiện 1 số menu ẩn như menu dẫn vào trang cá nhân để chỉnh sửa profile.

Trong phạm vi bài viết này chúng ta sẽ xử lý 3 ý đầu tiên, dùng lại design từ bài trước và chỉ tập trung vào flow + tính năng. Chúng ta sẽ dùng thêm plugin cho Wordpress và sử dụng thêm 1 số boilerplate code để cho tiện, plugin và boilerplate code này có thể dùng lại ở nhiều dự án sau.

1 số lưu ý trước khi bắt đầu:

  • Tại sao lại có bài viết này? Đây là series giao diện tại sao lại có bài viết về backend? login là phần quan trọng không thể thiếu, người làm giao diện (frontend) cũng cần biết cách để build tính năng login đơn giản. Làm frontend sẽ có kiểu riêng của frontend, đa phần sẽ là sử dụng linh hoạt các module đc build sẵn hoặc service bên thứ 3.

  • Wordpress được build bằng ngôn ngữ PHP, vậy có phải chúng ta sẽ phải học PHP? Định hướng của series này sẽ tập trung hoàn toàn vào Javascript, nên bạn sẽ không cần học PHP. Wordpress sẽ được coi như 1 công cụ Low Code, nó được build bằng gì không quá quan trọng. Chúng ta vẫn cần 1 số đoạn code PHP, tuy nhiên số lượng ít và mình sẽ cung cấp sẵn (nên mới gọi là boilerplate code).

  • Sau series này có thể mình sẽ viết thêm 1 series về backend để chúng ta cảm nhận được sự khác biệt.

Cài đặt plugin Ultimate Member, WP Code

Vào admin -> plugins -> add new plugin -> search các từ khóa "Ultimate Member", "WP Code" -> cài và active

Trong bộ code của mình có cài sẵn WP Code rồi. còn Ultimate Member nếu bạn nào cài lỗi thì có thể tải file zip trực tiếp từ wordpress.org/plugins và cho vào folder wp-content/plugins

Sau khi active thì bạn sẽ thấy thông báo: Ultimate Member needs to create several pages (User Profiles, Account, Registration, Login, Password Reset, Logout, Member Directory) to function correctly. Tiến hành bấm vào để tạo ra các page. Xong quá trình nó sẽ dẫn về trang settings của plugin

Trong đó có rất nhiều settings, bạn có thể check qua.

Giờ mở thử trang Login (tab ẩn danh) sẽ có giao diện như này:

Giao diện khá là cơ bản. Thử login thì thấy nó hoạt động, login bằng admin và được redirect về trang admin

Chúng ta có thể thay đổi cơ chế Redirect bằng cách vào Ultimate Member -> Forms -> Default Login -> Options: Redirection after Login

Bản chất khi Ultimate Member tạo trang Login cũng như các trang khác cho chúng ta, là nó tạo page và trong page nó chèn Shortcode vô. Bạn có thể hiểu Shortcode là 1 dạng component của Wordpress, được đóng gói thành 1 đoạn code ngắn và mang đi dùng ở mọi nơi.

Mở trang Login thấy đúng là nó đang dùng shortcode để nhúng form vô. Shortcode là 1 khái niệm rất phổ biến với Wordpress, và dĩ nhiên Elementor có hỗ trợ shortcode. Đây là mấu chốt để chúng ta chỉnh sửa Ultimate Member theo ý mình.

Các bước đại khái như sau:

  • Bấm Edit with Elementor để chuyển sang chế độ dùng Elementor

  • Dùng shortcode để hiện form ra tương tự như trước

  • Đến đây có 2 cách. 1 là dùng Custom CSS để style lại form giao diện theo ý mình

  • 2 là dùng display: none; để ẩn luôn cái form đó đi, và tự build 1 cái form khác, khi bấm các nút chức năng (Login/Signup) thì sẽ dùng JS điền và submit form đang ẩn

Cách đầu thì tùy vào design system hiện tại của bạn nếu hên xui giống giống theme của Ultimate Member thì dùng Custom CSS sẽ khá nhanh. Tuy nhiên, cách thứ 2 sẽ giúp chúng ta control được hoàn toàn giao diện.

Bài tập: Xử lý trường hợp đăng nhập sai phải hiện ra thông báo đăng nhập sai. Gợi ý: cũng sẽ inspect DOM của UM form để lấy thông tin.

Sau khi đã xong giao diện thì sẽ làm tiếp sang phần check trạng thái đăng nhập. mở WP Code (Admin -> Code Snippets) và tạo 1 snipet mới (Add Your Custom Code (New Snippet))

Đặt tiêu đề là PHP var to Window var, để loại code là PHP. sau đó nhập đoạn code sau vào:

function dump_current_user_to_json() {
    $current_user = wp_get_current_user();

    if ($current_user->ID !== 0) {
        $user_data = array(
            'ID' => $current_user->ID,
            'user_login' => $current_user->user_login,
            'user_email' => $current_user->user_email,
            'user_display_name' => $current_user->display_name,
            'user_avatar' => get_avatar_url( $current_user->ID, array( 'size' => 96 ) ),
            'user_roles' => array_values($current_user->roles),
            // Add more user data as needed
        );

        // Convert the user data to JSON
        $user_json = json_encode($user_data);
    } else {
        // If no user is logged in, output an empty object
        $user_json = '{}';
    }
    return $user_json;
}
function get_my_auth_info($a) {
    foreach ($a as $k => $v) {
        if (strpos($k, "wordpress_logged_in") !== false) {
            return "[ '".$k."',  '".$v."']";
        }
    }
    return "[]"; 
}
function custom_window_var_in_head() {
    $my_nonce = wp_create_nonce( 'wp_rest' );
    $my_auth = get_my_auth_info($_COOKIE);
    $user_json = dump_current_user_to_json();

//     $post_data = dump_post_data_json();

    echo '<script>console.log("Hello World"); '
        . 'var _my_nonce = "' .$my_nonce. '"; '
        . 'var _my_auth = ' .$my_auth. '; '
        . 'var _my_user = ' .$user_json. '; '
        . '</script>';
}

add_action( 'wp_head', 'custom_window_var_in_head' );

Sau đó save lại, bật chế độ Active. sau đó mở 1 page ra và chuột phải chọn View Page Source ta sẽ thấy đoạn này:

Và khi mở console gõ _my_user thì thấy có giá trị

Đó chính là cơ sở để ta check thông tin đăng nhập. Nếu mở ẩn danh lên thì nó sẽ như này:

Do đó để biết user có được đăng nhập hay không, thì chỉ cần check giá trị _my_user.ID xem tồn tại hay undefined, Sau đó dùng code JS để ẩn button login hiển thị tên + avatar.

Bài tập: làm tương tự với trang đăng ký và quên mật khẩu. sử dụng UI giống giống với UI của header.