Hướng dẫn tạo chức năng thông báo thời gian thực với Laravel và Reactjs

Trong các ứng dụng web hiện nay thì phần thông báo đã trở thành một thành phần rất quan trọng trong hệ thống website hay ứng dụng web của chúng ta nó được ứng dụng để thông báo tới người dùng những thông báo theo thời gian thực giúp người dùng nắm bắt thông tin một cách nhanh nhất. Hôm nay tôi sẽ hướng dẫn các bạn làm chức năng thông báo theo thời gian thực bằng Laravel và Reactjs một cách đơn giản và nhanh nhất.

Để làm được chức năng này bằng Laravel và Reactjs thì chúng ta cần tới 1 thư viện đó là Pusher. Đây là thư viện giúp chúng ta xây dựng các ứng dựng realtime sử dụng web socket một cách đơn giản và nhanh nhất mà bạn không phải mất quá nhiều thời gian để có thể tạo cho mình một ứng dụng websocket.

Đầu tiên ta hãy chạy lệnh sau để cài đặt thư viện Pusher cho Laravel.

composer require pusher/pusher-php-server

Sau khi đã cài thư viện vào Laravel ta cần tạo một tài khoản trên trang chủ Pusher.com cách đăng ký khá dễ hoặc bạn có thể chọn đăng ký bằng tài khoản Google cũng được.

Sau khi đã đăng ký và đăng nhập thành công thì bạn nhấn Get started bên phần channel để bắt đầu tạo một kênh mới cho ứng dụng của bạn cách tạo rất đơn giản bạn chỉ việc nhập tên cho ứng dụng của bạn chọn ngôn ngữ fontend bạn sử dụng ở đây tôi dùng Laravel echo và ngôn ngữ phía backend bạn sử dụng ở đây là framework Laravel sau đó nhấn Create là bạn hệ thống sẽ tự tạo một channel cho bạn sử dụng.

thông tin channel pusher

Sau khi Pusher đã tạo channel cho bạn thì bạn quay lại dự án Laravel của mình tại file .env bạn chỉnh sửa các thông tin cấu hình pusher theo thông tin mà pusher đã cung cấp cho bạn. Ví dụ trong file .env của tôi, tôi sẽ cấu hình như sau:

BROADCAST_DRIVER=pusher
PUSHER_APP_ID=1123388
PUSHER_APP_KEY=a91bfcfd34b8817c5109
PUSHER_APP_SECRET=c3ab45cb41a4a0afa5cd
PUSHER_APP_CLUSTER=ap1

Xong chỉ cần như vậy là bạn đã cấu hình xong pusher cho dự án của mình rồi, tiếp theo bạn cần chạy lệnh artisan để tạo một event mới trong dự án của bạn ở đây tôi đang làm chức năng thông báo nên tôi sẽ chạy lệnh như sau:

php artisan make:event NoticeEvent

Sau khi chạy lệnh trên Laravel sẽ tạo cho chúng ta một file Event mới có tên là NoticeEvent và việc của chúng ta bây giờ là chỉnh sửa lại nó để có thể sử dụng Boardcast của Pusher.

Trong file đó bạn phảiimplements interfaceShouldBroadcastcủa thư viện Pusher server sau đó bạn hãy chú ý đến hai hàm quan trọng nhất trong file event này là hàmbroadcastOnvà hàmbroadcastAs.

Ở hàm broadcastOn thì bạn hãy điền tên channel mà bạn đã tạo trên tài khoản pusher của bạn vô và broadcastAs thì bạn hãy điền tên event mà bạn đã tạo trên tài khoản pusher của mình vô. Như file NoticeEvent của tôi sẽ như thế này.

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;

use Illuminate\Broadcasting\InteractsWithSockets;

use Illuminate\Broadcasting\PresenceChannel;

use Illuminate\Broadcasting\PrivateChannel;

use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

use Illuminate\Foundation\Events\Dispatchable;

use Illuminate\Queue\SerializesModels;

class NoticeEvent implements ShouldBroadcast

{

    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message;

    public function __construct($message)

    {

        $this->message = $message;

    }

    public function broadcastOn()

    {

        return ['my-channel'];

    }

    public function broadcastAs()

    {

        return 'my-event';

    }

}
Như vậy là xong chúng ta đã viết file xong file event cho pusher rồi tiếp theo chúng ta sẽ làm phần gửi thông báo từ server xuống client khi có các thông báo được gửi đi.
Trong database tôi đã xây dựng một bảng Notice đơn giản như sau:

bảng Notice

Mực đích của bảng này của tôi là lưu lại các thông báo của người dùng trong trường hợp người dùng không online trên hệ thống thì khi họ online họ có thể biết được có những thông báo nào đã được gửi đến cho mình.

Rồi giờ chúng ta hãy xử lý các logic gửi thông báo tại file NoticeController. Tại file NoticeController tôi sẽ tạo một hàm addNotice như sau.

hàm xử lý notice

Nhiệm vụ của hàm này khá là đơn giản lưu thông tin thông báo vào database và kích hoạt sự kiên NoticeEvent để gửi thông báo đến các client đang kết nối vào boardcast thông qua hàm event như trên.

Đây là đoạn code kích hoạt sự kiện gửi message thông qua pusher.

code gửi message

Như vậy là xong chúng ta đã xử lý xong phần gửi message từ sever đi rồi. Tiếp theo chúng ta sẽ làm phần xử lý phía client.

Đầu tiên chúng cần tạo một component Notification cơ bản như sau.

component notification

Code:

return (

        <>

            <section className="logo">

                <i

                    style={{

                        fontSize: "34pt",

                        color: "white"

                    }}

                    className="fas fa-bell"

                ></i>

                <span

                    onClick={handledShow}

                    ref={refCount}

                    style={{

                        position: "absolute",

                        top: "10px",

                        right: "30px",

                        cursor: "pointer"

                    }}

                    className="count"

                >

                    0

                </span>

                <ul

                    style={show ? { display: "block" } : { display: "none" }}

                    className="listnotication"

                >

                    {listNotice}

                    {data.length > 0 ? (

                        <li onClick={handelMark} className="mark">

                            Đánh dấu tất cả đã đọc

                        </li>

                    ) : (

                        ""

                    )}

                </ul>

            </section>

        </>

    );
Cách tạo khá là đơn giản phải không nào.
Giờ chúng ta hãy chạy lệnh sau để cài thư viện pusher laravel echo vào dự án react của mình
npm install --save laravel-echo pusher-js
Sau khi cài xong ở component Notication chúng ta sẽ import thư viện laravel echo vào như sau:
import Echo from "laravel-echo";
Sau đó chúng ta sẽ cài đặt các cấu hình cho thư viện theo các thông tin mà trang pusher đã cung cấp cho bạn như thông tin cấu hình của tôi là như sau.
 window.Pusher = require("pusher-js");

    window.Echo = new Echo({

        broadcaster: "pusher",

        key: "a91bfcfd34b8817c5109",

        cluster: "ap1",

        forceTLS: true

    });
Sau khi đã cấu hình xong bạn hãy tạo một Effect để kết nối đến channel của bạn khi ứng dụng được khởi tạo như sau.
  useEffect(() => {

        var channel = window.Echo.channel("my-channel");

        channel.listen(".my-event", function(res) {

            setData([...data, res.message]);

        });

    }, []);
Như vậy là xong bạn đã kết nối đến boardcast Pusher của mình rồi giờ khi nào có message từ server được gửi đi thì client sẽ nhận được và sẽ thêm dữ liệu đã nhận được vào state data để hiển thị thông báo cho bạn.
Sau đây là toàn bộ code của component Notication
import React, { useEffect, useMemo, useRef, useState } from "react";

import { useDispatch, useSelector } from "react-redux";

import "../sass/notication.scss";

import { GETNOTICATION, READNOTICATION } from "../action/mainAction";

import { uniqueId } from "lodash";

import Echo from "laravel-echo";

import moment from "moment";

function Notication(props) {

    // Cáu hình thư viện pusher

    window.Pusher = require("pusher-js");

    window.Echo = new Echo({

        broadcaster: "pusher",

        key: "a91bfcfd34b8817c5109",

        cluster: "ap1",

        forceTLS: true

    });

    useEffect(() => {

        // lấy danh sách các thông báo từ server khi mà người dùng không online

        getNotification();

    }, []);

    useEffect(() => {

        // Kết nối đến Boardcast

        var channel = window.Echo.channel("my-channel");

        channel.listen(".my-event", function(res) {

            setData([...data, res.message]);

        });

    }, []);

    // State trạng thái hiển thị danh sách thông báo

    const [show, setShow] = useState(false);

    // State lưu trữ danh sách các thông báo

    const [data, setData] = useState([]);

    const dispatch = useDispatch();

    // Ref của thành phần hiển thị số thông báo chưa đọc

    const refCount = useRef();

    // Hàm lấy danh sách thông báo từ server sử dụng redux saga

    function getNotification() {

        dispatch({ type: GETNOTICATION, payload: setData });

    }

    // Hàm hiển thị danh sách các thông báo

    function handledShow() {

        if (show == false) {

            setShow(true);

        } else {

            setShow(false);

        }

    }

    // Hàm đánh dấu tất cả thông báo đều đã đọc

    function handelMark() {

        dispatch({ type: READNOTICATION });

        refCount.current.textContent = 0;

    }

    const listNotice = useMemo(() => showNotication(), [data]);

    // Hàm hiển thị danh sách thông báo

    function showNotication() {

        if (data.length > 0) {

            let number = 0;

            return data.map(item => {

                if (item.userId == localStorage.userId) {

                    number++;

                    refCount.current.textContent = number;

                    return (

                        <li

                            key={uniqueId("notification")}

                            className="itemNotication"

                        >

                            <section className="content-notication">

                                <p className="time">

                                    {moment(item.time).format("DD/MM/YYYY")}

                                </p>

                                <p style={{ marginBottom: 0 }}>{item.msg}</p>

                            </section>

                        </li>

                    );

                }

            });

        } else {

            return (

                <li className="itemNotication">

                    <section className="content-notication">

                        <p className="time"></p>

                        <p style={{ marginBottom: 0 }}>

                            Không có thông báo mới

                        </p>

                    </section>

                </li>

            );

        }

    }

    return (

        <>

            <section className="logo">

                <i

                    style={{

                        fontSize: "34pt",

                        color: "white"

                    }}

                    className="fas fa-bell"

                ></i>

                <span

                    onClick={handledShow}

                    ref={refCount}

                    style={{

                        position: "absolute",

                        top: "10px",

                        right: "30px",

                        cursor: "pointer"

                    }}

                    className="count"

                >

                    0

                </span>

                <ul

                    style={show ? { display: "block" } : { display: "none" }}

                    className="listnotication"

                >

                    {listNotice}

                    {data.length > 0 ? (

                        <li onClick={handelMark} className="mark">

                            Đánh dấu tất cả đã đọc

                        </li>

                    ) : (

                        ""

                    )}

                </ul>

            </section>

        </>

    );

}

export default Notication;
Như vậy là tôi đã hướng dẫn các bạn làm chức năng thông báo bằng laravel và reactjs một cách đơn giản nhất rồi, cảm ơn các bạn đã theo dõi và hẹn gặp lại các bạn ở các bài viết sau.

Hướng dẫn làm datatable phân cấp bằng javascript

Hôm nay trong một lần làm dự án mình được giao nhiệm vụ làm chức năng có cái bảng phân cấp dữ liệu giống cây thư mục vậy đó nó sẽ cho phép người dùng tích chọn các dòng của nó trong bảng theo thứ tự cha con, sau một hồi tìm tòi trên mạng để làm được chức năng này nhưng không có mấy gợi ý thì mình đã vô tình tìm được một ý tưởng có thể làm được cái datatable kiểu phân cấp thế này nên hôm nay mình sẽ chia sẻ với các bạn cách để làm nó.

Đầu tiên chúng ta sẽ tạo một dự án gồm có các file sau index.html, style.css, và script.js.

Về thư viện Jquery Tree Table bạn có thể tìm nó trên google và làm theo các bước hướng dẫn trong tài liệu thư viện để cài đặt nó vào dự án của chúng ta.

Đầu tiên trong file index.html bạn sẽ viết và dòng code đơn giản để tạo ra cấu trức bảng của chúng ta như sau.

Tạo cấu trúc bảng HTML

Chỉ cần tạo cấu trúc bảng đơn giản mà bạn muốn sử dụng là được. Ý tưởng làm cái bảng này là mình sẽ sử dụng thư viện Jquery TreeTable để tạo một bảng phân cấp sau đó chúng ta sẽ viết thêm những chức năng mà chúng ta muốn như của mình là các checkbox để cho người dùng có thể lựa chọn.

Sau khi bạn đã tạo được bảng bằng HTML xong thì bạn bắt đầu viết javascript cho nó nhé.

Đầu tiên chúng ta hãy nhìn cấu trúc dữ liệu data của chúng chúng ta xem như thế nào nhé.

Cấu trúc dữ liệu

Như cấu trúc dữ liệu của mình sẽ là một mảng chứa các đối tượng và chúng sẽ quan hệ với nhau bằng cặp id và IdParent tức là thằng con chứa id của thằng cha. Dựa vào cấu trúc này chúng ta hãy bắt đầu render các dòng để gắn vào trang html của chúng ta.

Đầu tiên viết một hàm để ánh xạ các control được sử dụng trên web vào các biến để sử dụng một cách thuận tiện hơn.

Như bạn thấy hàm này khá là đơn giản đúng không nào.

Sau đó chúng ta sẽ viết một hàm render dữ liệu ra HTML.

Render dữ liệu

Như bạn thấy hàm này rất đơn giản chúng ta chỉ lặp qua mảng dữ liệu được truyền vào hàm này và xét điều kiện kiểm tra là idParent có khác null hay không để in ra các dòng cha hoặc con trong bảng dữ liệu theo cấu trúc dữ liệu của Jquery TreeTable.

Tiếp theo chúng ta sẽ viết chức năng chọn tất cả của checbox chọn tất cả đầu tiên chức năng này viết khá đơn giản như sau

Checkbox chọn tất cả

Như bạn thấy trong đoạn code trên mình lắng nghe sự kiện click của checkbox chọn tất cả, khi check box này được chọn nó sẽ lấy tất cả các checkbox con có class là chk và sau đó lặp qua từng item trong danh sách con lấy được và đặt thuộc tính checked của nó theo thuộc tính checked của checkbox cha là chkAll.

Rổi giờ chúng ta sẽ viết tiếp sự kiện khi nhấn vào các nút checkbox của các nút con.

Gán sự kiện cho các nút con

Đoạn code trên đầu tiên chúng ta sẽ lấy danh sách các checkbox có class là chk để tiến hành gán sự kiện cho các checkbox con. Đầu tiên là lặp qua các phần tử của danh sách và gán sự kiện onclick cho nó khi click thì nó sẽ thực hiện hành động là lấy giá trị của checkbox vừa được click tức là id của item được chọn trong cái mảng data của mình sau đó sẽ lấy danh sách các các checkbox con thuộc checkbox đó thông qua id đã lấy được và nó sẽ lặp qua danh sách con này và gán thuộc tính checked của các node con theo node cha. Ở dưới chúng ta còn có hai hàm nữa là CheckStatusChkAll(),CheckParent(); mình sẽ nói ở phần sau.

Hàm CheckStatusChkAll() được sử dụng để kiểm tra xem có còn nút con nào được chọn không nếu còn thì nút chon tất cả sẽ được bật còn nếu không còn thì sẽ bỏ chọn nút chọn tất cả này.

Hàm kiểm tra nút cha

Còn hàm CheckParent() được sử dụng đển kiểm tra và đặt trạng thái của các nút cha khi click chọn nút con nó cũng kiểm tra và thực hiện hành động như hàm kiểm tra nút chọn tất cả thôi.

Hàm set chọn các nút cha

Hàm này cũng khá đơn giản nó sẽ lần theo cái idParent và tìm được nút cha và set giá trị checked bằng giá trị checked của con.

Thế là chỉ bằng vài bước đơn giản bạn đã có thể tạo được một bảng dữ liệu kiểu phân cấp mà có thể chọn checkbox theo cấu trúc cây rồi. HI vọng phần hướng dẫn này có thể giúp các bạn giải quyết được vấn đề mà mình gặp phải.

Bạn có thể download đầy đủ source code của phần hướng dẫn này tại đây

Cách chạy file .sql trong Laravel

Khi làm một phần mềm thì chắc hẳn chức năng backup và restore dữ liệu là một chức năng không thể thiếu rồi đúng không nào nhưng có một vấn đề là nếu file bạn xuất ra là file sql thì làm sao bạn có thể import nó lại được vào trong Mysql bằng Laravel hôm nay mình sẽ hướng dẫn các bạn cách chạy file sql trong larvel nhé.

Flow hàm chức năng của mình sẽ thực hiện những công việc như sau:

  • Đầu tiên bạn sẽ phải upload được file sql mà bạn muốn import vào cơ sở dữ liệu lên server.
  • Đọc dữ liệu từ file sql được upload lên và chạy các câu lệnh trong file sql đó để import dữ liệu vào cơ sở dữ liệu

Và để thực hiện chức năng này chúng ta cần xây dụng một hàm trong Controller của chức năng restore

<?php

namespace App\Http\Controllers;

use App\Http\Requests\Request;

use DB;

class BackupandRestoreDataController extends Controller

{

    public function Restore(Request $request)

    {

        if (!file_exists(storage_path('upload'))) {

            mkdir(storage_path('upload'));

        }

        # Lưu file đã được upload vào thư mục trên server

        $request->file->storeAs('upload', "backup.xlsx");

        $sql  = storage_path('app/upload' . '/backup.xlsx');

         // Chạy câu lệnh sql và set đồng ý kiểm tra các khoá ngoại trong bảng

        DB::statement("SET foreign_key_checks=1");

// Đọc dữ liệu từ file sql và thực hiện lệnh và sau đó chạy các lệnh sql bằng lệnh unprepared của laravel để có thể chạy được các lệnh sql raw

        

        DB::unprepared(file_get_contents($sql));

        

    }

}
Đó như vậy là bạn có thể import data vào cơ sở dữ liệu bằng file sql trong laravel rồi đó.

Cách tạo Report trong laravel

Khi bạn phát triển phần mềm thì có một công việc mà bạn luôn phải làm và nó luôn là một tính năng bắt buộc phải có trong các phần mềm đó chính là tính năng báo cáo. Nếu bạn phát triển phần mềm với công nghệ Winform hay ASP.Net thì bạn sẽ có những công cụ hỗ trợ rất mạnh giúp bạn có thể tạo được một báo cáo khá là nhanh chóng và dễ dàng nhưng nếu bạn phát triển phần mềm trên nền tảng PHP thì sẽ không có nhiều công cụ có thể giúp bạn tạo một report thật chuyên nghiệp và dễ dàng. Vậy đâu sẽ là giải pháp cho vấn đề này. Thực ra vẫn có một số công cụ hỗ trợ tạo báo cáo cho những phần mềm phát triền trên nền tàng PHP hay các framework được viết bằng PHP như Laravel và hôm nay tôi muốn hướng dẫn mọi người các tạo report trên Laravel bằng một công cụ giúp bạn tạo được các mẫu report chuyên nghiệp đó chính là phần mềm StimulSoft Report Ultimate. Đây là một phần mềm tạo báo cáo rất trực quan và chuyên nghiệp.

Đầu tiên để tạo một mẫu report cho sản phẩm mà mình đang phát triển thì bạn sẽ cần tạo một file mẫu báo cáo bằng công cụ thiết kế của Stimulsoft đã công việc khá là đơn giản và dễ dàng bạn chỉ việc mở công cụ Stimulsoft Desgin và kéo thả các thành phần mà bạn mong muốn vào trong mẫu Report của mình.

Đề tạo một mẫu báo cáo cơ bản thì bạn sẽ cần kéo vô hai thành phần bắt buộc phải có là Report Title Band và Report Summary Band đây chính là hai thành phần sẽ chứa phần đầu tiêu đề của báo cáo và phần thân của báo cáo.Sau đó bạn có thể chèn bất cứ thành phần náo vào bên trong hai thành phần này như hình ảnh hay văn bản.

Đề có thể hiển thị được dữ liệu được trả về từ server của bạn thì bạn cũng cần kéo DataBand vào báo cáo của mình để có thể hiển thị dữ liệu vào báo cáo của mình.

Nếu trong báo cáo của bạn có bảng biểu và bạn muốn tạo bảng trong báo cáo của mình thì bạn sẽ cần thêm hai thành phần khác vào báo cáo của mình là Headerband và FooterBand đây là hai thành phần sẽ hiển thị phần đầu và phần cuối của dải dữ liệu khi dữ liệu của bạn được hiển thị hoàn tất.

Sau khi bạn đã thiết kế hoàn tất mẫu báo cáo của mình tiếp theo bạn cần tạo nguồn dữ liệu cho báo cáo để có thể nhận dữ liệu được phản hồi từ server.

Để tạo nguồn dữ liệu mới thì bạn hãy chuyển sang tab từ điển và nhấn chuột phải vào mục các nguồn dữ liệu và chọn tạo nguồn dữ liệu mới.

Tại hộp thoại chọn nguồn dữ liệu bạn có thể chọn rất nhiều kiểu nguồn dữ liệu cho mẫu báo cáo của mình nhung ở đây mình sẽ chọn Dataset, Datable.

Hộp thoại tạo nguồn dữ liệu hiện ra ở hộp thoại này bạn có thể đặt tên cho nguồn dữ liệu và tạo các bảng dữ liệu có các cột và tên sao cho giống với các dữ liệu mà bạn đã trả về từ server hãy nhớ tên của các bảng cũng như các cột trong bảng phải giống y hệt với dữ liệu được trả về từ server, sau khi đã tạo xong bạn hãy nhấn đồng ý để lưu lại nguồn dữ liệu đã tạo.

Sau khi bạn đã tạo xong nguồn dữ liệu và muốn gắn các dữ liệu bạn đã tạo vào báo cáo của mình thì rất đơn giản bạn chỉ cần chọn thành phần muốn gắn sau đó chọn ô cột dữ liệu và chọn cột dữ liệu mà bạn muốn gắn vào báo cáo.

Và StimulSoft cũng cho phép bạn có thể viết các biểu thức tại ô biểu thức để có thể tuỳ chỉnh các dữ liệu theo ý muốn của bạn.

Bạn cũng có thể tạo các biến để có thể chuyền các biến từ bên ngoài vào báo cáo của mình.

Cách làm rất đơn giản click chuột phải tại tab từ điển và chọn tạo biến mới.

Tại hộp thoại tạo biến mới bạn có thể nhập tên của biến và chọn kiểu dữ liệu cho biến mà bạn sẽ tạo và nhấn đồng ý để lưu biến đó lại

để hiển thị biến đó thì rất đơn giản bạn có thể kéo thả biến đó vào report hoặc bạn có thể chọn vào thành phần bạn muốn hiển thị và tại phàn biểu thức bạn có thể nhập vào theo cấu trúc sau để hiển thị biến đó ra: {tên biến};

Sau khi bạn đã tạo xong mẫu báo cáo của mình bằng phần mềm desginer của stimulsoft thì bạn có thể lưu mẫu báo cáo của mình vào một thư mục trong dự án của bạn.

Sau đó bạn hãy coppy các file js cần thiết của stimulsoft vào project của bạn và nhúng nó vào file master của bạn.

Bạn sẽ cần coppy và nhúng vào các file js sau:

  <!-- Report Viewer Office2013 style -->

  <link href="{{asset('js/libReport/Reports.JS/Css/stimulsoft.viewer.office2013.whiteblue.css')}}" rel="stylesheet">

  <link href="{{asset('js/libReport/Reports.JS/Css/stimulsoft.designer.office2013.whiteblue.css')}}" rel="stylesheet">

  <!-- Stimusloft Reports.JS -->

  <script src="{{asset('js/libReport/Reports.JS/Scripts/stimulsoft.reports.js')}}" type="text/javascript"></script>

  <script src="{{asset('js/libReport/Reports.JS/Scripts/stimulsoft.reports.maps.js')}}" type="text/javascript"></script>

  <script src="{{asset('js/libReport/Reports.JS/Scripts/stimulsoft.viewer.js')}}" type="text/javascript"></script>

  <script src="{{asset('js/libReport/Reports.JS/Scripts/stimulsoft.designer.js')}}" type="text/javascript"></script>

Sau khi đã nhúng các file js cần thiết vào thì tại nơi bạn muốn hiển thị báo cáo thì bạn hẫy tạo một thẻ div và đặt một id tuỳ ý, ở đây tôi đặt là content.

sau đó tại file js của bạn thì bạn có thể nhúng đoạn mã JS sau vào:

 // Load file key ban quyen cho phan mem

Stimulsoft.Base.StiLicense.loadFromFile("js/libReport/Reports.JS/license.key");

    //đặt ngôn ngữ

    Stimulsoft.Base.Localization.StiLocalization.setLocalizationFile("js/libReport/Reports.JS/Localization/vi.xml");

    // Đặt chế độ toàn màn hình cho người xem

    var options = new Stimulsoft.Viewer.StiViewerOptions();

    options.height = "200vh";

    options.appearance.scrollbarsMode = true;

    options.toolbar.showOpenButton = false;

    options.toolbar.printDestination = Stimulsoft.Viewer.StiPrintDestination.Direct;

    options.appearance.htmlRenderMode = Stimulsoft.Report.Export.StiHtmlExportMode.Table;

    options.toolbar.showAboutButton = false;

    // options.appearance.fullScreenMode = true;

    // Tạo trình xem báo cáo với các tùy chọn được chỉ định

    var viewer = new Stimulsoft.Viewer.StiViewer(options, "StiViewer", false);

// Khởi tạo view 

    viewer.renderHtml('content');

    // Create a new report instance

    // Tạo một ví dụ báo cáo mới

    var report = new Stimulsoft.Report.StiReport();

    // Load file báo cáo từ url

    report.loadFile("../../../report/2.2.2quyetdinhhotromaitangphi.mrt");

    // Gán báo cáo cho người xem, báo cáo sẽ được xây dựng tự động sau khi hiển thị trình xem

    viewer.report = report;

    var viewer = null;

    var designer = null;
Và ở tại hàm hiển thị báo cáo sau khi bạn thực hiện hành động xuất ra báo cáo thì bạn hãy chèn đoạn JS này vào.
 //view report

          Stimulsoft.Base.StiLicense.loadFromFile("js/libReport/Reports.JS/license.key");

            //đặt ngôn ngữ

            Stimulsoft.Base.Localization.StiLocalization.setLocalizationFile("js/libReport/Reports.JS/Localization/vi.xml");

            // Set full screen mode for the viewer

            // Đặt chế độ toàn màn hình cho người xem

            var options = new Stimulsoft.Viewer.StiViewerOptions();

            options.height = "200vh";

            options.appearance.scrollbarsMode = true;

            // options.toolbar.showDesignButton = true;

            options.toolbar.showOpenButton = false;

            options.toolbar.printDestination = Stimulsoft.Viewer.StiPrintDestination.Direct;

            options.appearance.htmlRenderMode = Stimulsoft.Report.Export.StiHtmlExportMode.Table;

            options.toolbar.showAboutButton = false;

            // options.appearance.fullScreenMode = true;



            //Viewer

            var viewer = new Stimulsoft.Viewer.StiViewer(options, "StiViewer", false);

            viewer.renderHtml('content');

            var report = new Stimulsoft.Report.StiReport();

            // var datas = { "databases" : [{"libelle":"myLibelle1","libcourt":"myLibCourt1","name":"name1"},{"libelle":"myLibelle2","libcourt":"myLibCourt2","name":"name2"}]};

            var datas = data;

//Khoi tao mot dataset

            var dataSet = new Stimulsoft.System.Data.DataSet("datas");

// Gan du lieu tu Json tra ve vao dataset

            dataSet.readJson(datas);

            report.regData(dataSet.dataSetName, "", dataSet);

            // report.dictionary.synchronize();

            report.loadFile("../../../report/2.2.2quyetdinhhotromaitangphi.mrt");

// Lay cac bien duoc tao trong bao cao

            let nam = report.dictionary.variables.getByName('nam');

            let thang = report.dictionary.variables.getByName('thang');

            let ubnd = report.dictionary.variables.getByName('ubnd');

            let ngayht = report.dictionary.variables.getByName('ngayht');

            let thanght = report.dictionary.variables.getByName('thanght');

            let namht = report.dictionary.variables.getByName('namht');

// Gan gia tri cho cac bien 

            let ubndText = $('#cbxa option:selected').text();

            let rpthang = $('#cbchonthang').val();

            rpthang = rpthang.split('/');

            let Current = new Date();

            ubnd.value = ubndText;

            thang.value = rpthang[1];

            nam.value = rpthang[2];

            ngayht.value = Current.getDate();

            thanght.value =Current.getMonth()+1;

            namht.value = Current.getFullYear();

            report.dictionary.synchronize();

// gan report vào view

            viewer.report = report;
Như vậy là bạn đã hoàn thành việc tạo và sử dụng report trong project PHP của mình rồi đấy. hi vọng qua bài viết này bạn sẽ có một công cụ mới giúp bạn có thể dễ dàng tạo các báo cáo cho project của mình.

Khắc phục lỗi 404 khi cập nhật bài viết trong WordPress khi dùng Cpanel

Đây là một trong những hiện tượng hiếm gặp. Tuy nhiên khi gặp phải lỗi này, bạn sẽ khó biết được cách xử lý chính xác.

Trong suốt hơn 5 năm làm WordPress của mình, những hiện tượng được xem là hiếm gặp như thế này thật ra không phải là hiếm. Hôm nay mình xin chia sẻ với bạn cách để khắc phục hiện tượng lỗi 404 xuất hiện khi cập nhật bài viết. Và lỗi này xuất hiện khi bạn đang dùng Cpanel trên Linux nhé.

Nguyên nhân xuất phát lỗi

Cpanel là một hệ thống quản trị hosting trả phí tốt nhất và phổ biến nhất hiện nay. Hệ thống này tích hợp nhiều tiện ích cho việc xây dựng và quản lý hosting.

Trong Cpanel có một chức năng có tên là ModSecurity. Nó là một phần trong việc bảo mật xuất phát từ bên trong các loại mã nguồn. Việc kích hoạt ModSecurity là cần thiết. Tuy nhiên một số mã nguồn cũ như các phiên bản WordPress cũ, website bị viruts hoặc các website WordPress có sử dụng các plugin có phương thức truyền file kém bảo mật sẽ bị lỗi 404 khi cập nhật bài viết.

Cách khắc phục lỗi 404

Để khắc phục lỗi này. Bạn có 2 cách,

  • 1: Tắt ModSecurity trong Cpanel. Tuy nhiên việc này không được khuyến khích sử dụng. Vì một website cần có độ bảo vệ an toàn từ bên trong. Tuy nhiên để khắc phục tạm thời để website vận hành ổn định. Bạn cần tắt ModSecurity. Để tắt bạn thực hiện theo các bước sau:
Truy cập đến phần Security và chọn ModSecutity
Nhấn vào Disable để vô hiệu hóa toàn bộ
Nếu muốn vô hiệu hóa toàn bộ bạn nhấn vào Disable All. Nếu muốn vô hiệu hóa từng domain riêng lẻ thì nhấn nút On – Off bên dưới.
  • Nâng cấp phiên bản WordPress, Theme, và Plugin là phương pháp thứ 2 để giải quyết lỗi. Cách này sẽ giúp giải quyết triệt để vấn đề lỗi 404. Tuy nhiên một số website sẽ gặp lỗi trầm trọng hơn về việc mã nguồn, giao diện và Plugin có thể không phù hợp nhau, dẫn đến xung đột.

Một trong những lời khuyên của mình đó là hãy tìm đến đơn vị thiết kế website code tay trên nền WordPress chuẩn nhất. TuanDC mình đã thực hiện hơn 30 dự án code tay WordPress và tất cả đều ổn định qua năm tháng. Bất chấp việc WordPress có cập nhật phiên bản mới nhất.

Giới hạn của WordPress tới đâu cho trang web thương mại điện tử?

Trong bài viết này chúng ta cùng tìm hiểu về giới hạn của WordPress dành cho trang TMĐT.

WordPress đang là một trong những CMS tốt nhất. Nó sở hữu khả năng tùy biến vô hạn để làm tất cả mọi website bạn muốn. Một website thương mại điện tử (TMĐT) sử dụng WordPress không có gì là mới lạ. Nhưng có bao giờ bạn tự hỏi giới hạn của WordPress là tới đâu khi sử dụng cho trang TMĐT?. Trong bài viết này chúng ta cùng tìm hiểu về giới hạn của WordPress dành cho trang TMĐT.

Giải quyết các yêu cầu của trang TMĐT

Một trang TMĐT tối thiểu phải đăng được sản phẩm, hiển thị, thao tác đặt hàng,… Ngoài ra, trong một môi trường cạnh tranh như ngày nay. Cùng với những yêu cầu cao về trải nghiệm người dùng. Thì một trang TMĐT phải đáp ứng nhiều hơn thế.

Tôi lấy ví dụ về trang web thương mại điện tử Mỹ Phẩm SIME BEAUTY tại simebeauty.com. Đây là một trang TMĐT có nhiều yêu cầu hấp dẫn như Affiliate, “trải nghiệm mua sắm tại chỗ”, hệ thống marketing Inbound và Outbound,… Website hướng đến khả năng quản trị tự động trên 60%.

Trải nghiệm mua sắm “Tại chỗ” trên SIME BEAUTY

Ngoài ra, WordPress còn có thể giải quyết rất nhiều các yêu cầu phức tạp khác cho trang TMĐT. Trong tương lai gần, các trang web TMĐT bằng WP có thể áp dụng trí tuệ nhân tạo AI để bán hàng tốt hơn.

Tốc độ

WordPress chạy rất nhanh. Đúng, nhưng nó chỉ thật sự nhanh khi website “chưa có gì”. Còn nếu website đã có một lượng người dùng lớn, cùng “núi” data lớn thì website sẽ trở nên nặng nề và chậm chạp.

WordPress có thật sự giúp trang TMĐT chạy nhanh?

Mặc dù sẽ chậm dần theo sự phát triển của website nhưng luôn có cách để tối ưu. Một trong những phương pháp giảm tải tốt nhất là kết hợp các nền tảng khác nhau. Ví dụ như hiển thị sản phẩm, quản lý sản phẩm do WordPress xử lý. Nhưng đơn hàng và khách hàng thì do một nền tảng khác xử lý thông qua các API hoặc kết nối ngầm.

Vấn đề này Tiki, một trong những trang TMĐT lớn nhất Việt Nam đã và đang sử dụng.

Bảo mật

Sức mạnh bảo mật phụ thuộc vào đội ngũ vận hành của bạn. Bất kể một nền tảng nào cũng sẽ có một lỗ hổng nhất định. WordPress dĩ nhiên là dễ bị tấn công hơn những nền tảng khác, do sự phổ biến của nó. Tuy nhiên nó cũng được xem là một CMS bảo mật nhất do có nhiều chuyên gia bảo mật cùng phát triển.

Vận hành – Nâng cấp

WordPress không khó để nâng cấp, WordPress cũng rất dễ để vận hành. Do đó bạn hoàn toàn có thể tự vận hành và nâng cấp nó với chi phí cực kỳ rẻ.

Bạn cũng nên lưu ý là WordPress chỉ dùng cho trang TMĐT tốt nhất khi bạn có một đội ngũ xây dựng và vận hành chuyên nghiệp. Nếu không hãy tìm đến những phương pháp khác an toàn hơn.

Tóm lại WordPress hoàn toàn có thể sử dụng để làm một trang TMĐT. Giới hạn của nó phụ thuộc vào tài nguyên hệ thống, độ lớn dữ liệu, đội ngũ vận hành. Như phía trên tôi có nhắc đến SIME BEAUTY, một website TMĐT về mỹ phẩm. Với hơn 500k User hàng tháng, website vẫn hoạt động rất nhịp nhàng và ổn định.

Những ưu nhược điểm của Website bán hàng sử dụng Woocommerce

Hôm nay chúng ta hãy cùng tìm hiểu những ưu nhược điểm của website bán hàng sử dụng Woocommerce nhé.

Khi nhắc tới việc làm Website bán hàng trực tuyến thì bạn sẽ có hai cách để tạo nên Website đó, chính là Website tự code và Website được xây dựng bằng một nền tảng nào đó với các công cụ hỗ trợ như xây dựng website bán hàng hàng bằng WordPress. với Woocommerce chẳng hạn đây có lẽ là việc chả xa lạ gì với bạn nữa nhưng có bao giờ bạn tự hỏi một câu hỏi là xây dựng Website báng hàng bằng Woocommerce thì sẽ có những ưu nhược điểm gì chưa. Hôm nay chúng ta hãy cùng tìm hiểu những ưu nhược điểm của website bán hàng sử dụng Woocommerce nhé.

Đầu tiên chúng ta hãy nói đến những ưu điểm của website bán hàng sử dụng Woocommerce nhé.

Đầu tiên cái mà bạn có thể dễ dàng nhận ra nhất đó là khả năng xây dựng website bán hàng bằng Woocoomerce rất đơn giản và không tốn nhiều thời gian công sức để xây dựng một website bán hàng bạn không cần bỏ ra quá nhiều thời gian để thiết kế cũng như code để tạo nên một website bán hàng chuyên nghiệp vì tất cả điều đó đều đã được plugin Woocommerce lo hết rồi bạn chỉ việc tập trung vào chuyên môn của mình là code giao diện website sao cho chuyên nghiệp nhất thôi.

Ưu điểm thứ hai đó chính là có nhiều plugin đa dạng hỗ trợ cho Woocommerce. Với Woocommerce bạn sẽ có một kho plugin đa dạng hỗ trợ hầu như tất cả các yêu cầu mà bạn cần cho website bán hàng của bạn.

Ưu điểm thứ ba là Woocommerce sẽ giúp bạn có một hệ thống quản lý bán hàng chuyên nghiệp từ việc quản lý hàng hoá, kho hàng cho tới việc quản lý các đơn hàng đã bán và thống kê doanh số của bạn một cách dễ dàng và đơn giản mà bạn không phải đau đầu thiết kế ra những chức năng đó hay thậm chí Woocommerce có thể cung cấp cho bạn rất nhiều phương thức thanh toán đơn hàng bao gồm cả các phương thức thanh toán bằng thẻ visa thì Woocommerce cũng hỗ trợ tận răng cho bạn.

An toàn bảo mật và luôn có sự hỗ trở tốt nhất với Woocommerce bạn sẽ được cập nhật những phiên bản mới nhất cũng như sẽ có được sự hỗ trợ cúng như các bản vá bảo mật tốt nhất. Và Woocommerce cũng sẽ đảm bảo an toàn bảo mật cho các giao dịch của bạn.

Rồi đó là những ưu điểm mà Woocommerce có thể đem lại cho bạn giờ chúng ta hãy nói đến những nhược điểm của Woocommerce nhé.

Đầu tiên là khả năng mở rộng các tính năng theo ý muốn. Woocommerce là một plugin thương mại điện tử được xây dựng sẵn rồi nên bạn chỉ việc cài vô và dùng thôi nhưng đôi lúc bạn cũng muốn website bán hàng có một số tính năng của riêng bạn và bạn muốn thêm nó vào Woocommerce nhưng việc này là rất khó vì Woocommerce đã được xây dựng sẵn rẩt chặt chẽ rồi và nếu bạn muốn thêm một tính năng mới do bạn tự viết thì bạn sẽ phải can thiệp chỉnh sửa lại Woocommerce việc này sẽ gây ra sự bất ổn định cho hệ thống website của bạn và đôi khi tính năng mà bạn phát triển thêm vào sẽ không tương thích tốt với Woocommerce.

Thứ hai là khó tuỳ biến theo nghiệp vụ bán hàng của riêng bạn. Woocommerce là một plugin thương mại điện tử được xây dựng theo một nghiệp vụ bán hàng có sẵn và phổ biến nhưng nếu bạn có một nghiệp vụ bán hàng khác hoặc hơi khác một chút và bạn có nhu cầu tuỳ chỉnh lại woocommerce cho phù hợp với nghiệp vụ của bạn thì đây là điều rất khó và gần như là không thể làm được.

Như vậy với Woocommerce bạn hoàn toàn có thể tạo được một website bán hàng chuyên nghiệp một cách đơn giản và dễ dàng nhưng cái gì cũng có hai mặt của nó và Woocommerce cũng không cùng ngoại lệ cũng có những ưu điểm và nhược điểm mà mình đã trình bày ở trên nên hi vọng sau khi đọc xong bài này những ưu điểm, nhược điểm của Woocommerce mà mình đã nêu bên trên phần nào giúp bạn có cái nhìn tốt hơn khi lựa chọn nền tảng để tạo website cho riêng mình.

Tạo form reset mật khẩu WordPress Ngoài Front-end không cần Plugin

Khi lập trinh các Website mà có phần đăng nhập thì hẳn bạn sẽ thường gặp một bộ đôi quen thuộc là form đăng nhập và form quên mật khẩu luôn là hai chức năng không thể thiếu cho website. Và để làm những form reset mật khẩu ngoài font-end trong WordPress thì cũng khá là đơn giản bạn chỉ cần sử dụng plugin là xong nhưng việc này sẽ vô tình làm cho trang web của bạn trở nên nặng hơn do quá nhiều plugin và khó bảo trì hơn nên có thể bạn không thích việc xài plugin này chỉ cho chức năng reset mật khẩu mà thội. Hôm nay mình sẽ hướng dẫn các bạn tạo form reset mật khẩu WordPress ngoài Front-end mà không cần plugin.

// AJAX FOGOT
add_action( 'wp_ajax_forgotajax', 'forgotajax_init' );
add_action( 'wp_ajax_nopriv_forgotajax', 'forgotajax_init' );
function forgotajax_init() {
$email = (isset($_POST['usernamelog']))?esc_attr($_POST['usernamelog']) : '';
$email = trim($email);
$result ="";

$random_password = wp_generate_password( 12, false );
if (! is_email( $email )){
    $result ="NOT_EMAIL";
}
else if( ! email_exists( $email ) ) {
    $result ="NOT_HAVE_EMAIL";
}
else {
    $user = get_user_by( 'email', $email );
    $update_user = wp_update_user( array (
                    'ID' => $user->ID, 
                    'user_pass' => $random_password
                )
            );
            if( $update_user ) {
                $result ="CHANGE_SUCCES";   
                $to = $email;
                $subject = 'Mật khẩu mới của bạn';
                $sender = get_option('name');
                $message = 'Đây là mật khẩu mới của bạn: '.$random_password;

                $headers[] = 'MIME-Version: 1.0' . "\r\n";
                $headers[] = 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
                $headers[] = "X-Mailer: PHP \r\n";
                $headers[] = 'From: '.$sender.' < '.$email.'>' . "\r\n";

                $mail = wp_mail( $to, $subject, $message, $headers );
                if( $mail ){
                    $result ="CHANGE_SUCCES";
                }

            } else {
                $result ="CHANGE_FAIL";   
            }
 }

wp_send_json_success($result);
die();
}
// END AJAX FOGOT

Trên đây là đoạn code đơn giản để bạn có thể tạo form quên mật khẩu ngoài Font-end mà bạn không cần phải cài bất cứ một plugin nào cả.

Cách tạo Landing Page đơn giản bằng WordPress mà không cần biết code

Trong bài viết này, mình sẽ chia sẻ với bạn các bước để tạo một Landing Page bằng WordPress mà không phải code một dòng nào.

Landing page là một dạng website giúp tăng tỷ lệ chuyển đổi tốt nhất. (để biết vì sao hãy đọc bài: Landing Page là gì? Cách tạo một Landing Page tốt để bán hàng) có nhiều cách để có thể có được một trang Landing Page như sử dụng các dịch vụ cung cấp có sẵn, thuê coder, hoặc tự tạo cho mình một Landing Page với các CMS như WordPress. Trong bài viết này, mình sẽ chia sẻ với bạn các bước để tạo một Landing Page bằng WordPress mà không phải code một dòng nào.

Cài đặt và kích hoạt Plugin Elementor

Đầu tiên bạn hãy tải và cài đặt Plugin Elementor vào WordPress đây là Plugin cho phép bạn xây dựng trang Web bằng thao tác kéo thả rất đơn giản và nhanh chóng, nó rất phù hợp với những người không biết code nhưng vẫn muốn tự mình xây dựng một trang web thì với plugin Elementor bạn hoàn toàn có thể tự xây dựng một landing page cho mình mà chẳng cần biết một tí code gì cả dù biết một chút vẫn tốt hơn.

OK đầu tiên ta vô phần quản lý plugin của WordPress và chọn cài mới sau đó gõ vào ô tìm kiếm Elementor để tìm kiếm plugin Elementor trong kho plugin của WordPress.

Sau khi đã tìm thấy plugin hãy nhấn cài đặt để cài đặt plugin.

cài đặt plugin

Sau khi cài đặt xong hãy nhấn kích hoạt plugin để có thể sử dụng plugin nhé.

kich hoat plugin

Sau khi kích hoạt xong bạn hãy nhấn vào nút Create Your First Page để bắt đầu tạo trang web đầu tiên của mình nhé.

Đầu tiên bạn hãy nhấn vô biểu tượng bánh răng để vô phần cài đặt tại phần page layout bạn hãy chọn Elementor Canvas để layout phủ toàn bộ trang web.

Sau đó bạn chọn vào hình thư mục để vào thư viện mẫu của plugin ở đây bạn sẽ có rất nhiều mẫu trang web cho bạn chọn lựa bạn hãy chọn cho mình một mẫu website ưng ý nhất.

Sau đó hãy nhấn vô nút chèn để chèn mẫu website vô page của bạn.

Như vậy là bạn đã chèn thành công mẫu website cho trang web của mình tiếp theo là bạn hãy chình sửa mẫu website này theo ý muốn của bạn như bạn có thể xoá hoặc thêm các thành phần khác vào trang web của bạn từ thanh công cụ hoặc bạn cũng có thể thiết kế thêm bớt các block trong trang web đó.

Để thêm một khối mới vào thì bạn hãy chọn vị trí mà bạn muốn thêm một khối mới vào và di chuột lên đầu block đó để hiện các tuỳ chọn tại đó và bạn có thể chọn thêm mục để thêm một mục mới.

Và sau khi đã có mục mới bạn có thể chọn bố cục cho mục này.

Chọn bố cục mà bạn muốn áp dụng cho mục này.

Sau khi đã chọn được bố cục cho trang web bạn hoàn toàn có thể thoải mái kéo các widget mà bạn muốn vào đây.

Và với các widget mà bạn kéo vào thì Elementor sẽ hỗ trợ rất nhiều các tuỳ chỉnh cho widget đó để bạn có thể thoải mái tuỳ chỉnh trang web đó theo ý mình.

Sau khi bạn bạn đã chỉnh sửa cũng như hoàn thiện trang landing page của mình thì bạn có thể lưu lại và xuất bản trang landing page này để có thể hiển thị trên internet.

Nhấn vô nút xuất bản để xuất bản trang web.

Và cuối cùng để Landing page của bạn có thể hiển thị trên trang WordPress của bạn thì bạn phải cài đặt lại WordPress một chút.

Nhấn vào biểu tượng menu để mở menu của Elementor.

Nhấn vô nút thoát về bảng tin để thoát khỏi Elementor.

Chọn vô mục giao diện và nhấn vô mục tuỳ biến để có thể bắt đầu sửa giao diện trang web của bạn.

Tại đây bạn hãy chọn cài đặt trang chủ.

Sau đó bạn hãy chọn trang tĩnh phần trang chủ bạn hãy chọn page mà bạn vừa tạo ra trong WordPress sau đó bạn hãy nhấn đắng để lưu lại toàn bộ các cài đặt của bạn.

Như vậy là mình đã giới thiệu đến các bạn cách để tạo một landing page mà bạn không cần phải biết một chút code nào cả. Với cách này bạn có thể thoải mái tạo cho mình một landing page chuyên nghiệp một cách dễ dàng nhất.

5 giờ tạo website bằng WordPress cực kỳ đơn giản và chuyên nghiệp

Bạn không muốn có một website để quảng bá sản phẩm hay đơn giản hơn là bạn muốn có một blog cá nhân để ghi lại những cảm nghĩ hãy viết những bài viết hay để chia sẻ với bạn bè và mọi người. Nhưng có một vấn đề xảy ra đó là bạn không hề biết lập trình bạn không biết làm thế nào để tạo nên một trang web nhưng bạn lại đang muốn tự tạo một trang web cho riêng mình vậy chúng ta có giải pháp nào cho vấn đề này không? Đừng lo lắng hôm nay mình sẽ hướng dẫn các bạn tạo một trang web bằng WordPress cực kỳ đơn giản và chuyên nghiệp. Nào chúng ta hãy cùng bắt đầu 5 giờ tạo website bằng WordPress cực kỳ đơn giản và chuyên nghiệp thôi nào.

Chuẩn bị

Đầu tiên bạn hãy cài đặt XAMPP lên máy bạn đây là một phần mềm tạo localhost để có thể chạy được các website viết bằng PHP sau đó bạn cài WordPress vào localhost của bạn, và bạn cũng phải có một phần mêm code editor tốt mình thì hay dùng visual code.

Những hướng dẫn cài đặt này đều đã có những bài viết hướng dẫn trên mạng nên bạn có thể tìm trên đó và làm theo rất dễ dàng.

Cài đặt dự án web của bạn

Đầu tiên bạn hãy tạo một thư mục chứa dự án của bạn tại đường dẫn: C:\xampp\htdocs\[thư mục wordpress của bạn]\wp-content\themes

tạo thư mục chứa dự án

Sau khi đã có thư mục chứa dự án rồi bạn hãy truy cập đường dẫn https://github.com/squibbleFish/theme-bones để có thể tải về gói started theme Bones.

Giải nén file theme started.

Sau khi tải về hãy giải nén nó vào thư mục dự án của bạn.

kích hoạt theme

Bạn có thể kích hoạt theme ở phần giao diện để bắt đầu sử dụng theme này.

Theme sau khi kích hoạt

Về cơ bản thì đây là một core theme cơ bản được xây dựng sẵn những thứ cơ bản rồi bạn không cần phải quan tâm quá nhiều tới việc code toàn bộ dự án từ đầu nữa mà bạn có thể chỉnh sửa lại theo ý thích của mình và hôm nay mình sẽ hướng dẫn các bạn tạo một trang blog đơn giản bạn chỉ cần biết HTML và CSS và một chút PHP thôi là có thể làm được rồi. Giờ chúng ta hãy bắt đầu tạo trang web cho riêng mình nhé.

Đầu tiên để bắt đầu tạo cho mình một trang wordpress riêng thì bạn phải coppy các tài nguyên có trong bộ template của bạn như các file css, js hay các file hình ảnh hoặc âm thanh vào thư mục dự án của bạn.

Giờ bạn hãy mở file head.php trong thư mục dự án của bạn lên bằng code editor của bạn đồng thời cũng mở file index.html của template của bạn lên.

Giờ bạn hãy nhìn vào file index.html bạn sẽ thấy các thẻ html quen thuộc với bạn hãy nhìn vào đó để xác định cấu trúc website để chọn được đoạn code bạn sẽ coppy vào phần đầu của website trong file header.php thông thường ở phần đầu của website sẽ có những phần không thay đổi là phần menu, logo và banner đây là những phần không bao giờ thay đổi là phần chung của website vì thế bạn có thể cắt phần này để đưa vào file header.php như mẫu template của mình có những phần không thay đổi là menu và banner nên mình sẽ coppy những đoạn code thuộc phần đó vào file header.php.

phần headder

Mình có một lưu ý nho nhỏ với các bạn là trong phần header sẽ có những file css và js của template được nhúng vào đó và để sử dụng được những file js và css này trong wordpress bạn cần nhúng các file này vào wordpress trong file function.php như sau.

wp_enqueue_style( 'tên','đường dẫn css' );

thêm css vào theme

Và trong phần head của trang header.php bạn hãy gọi hàm:

wp_head();
Để có thể load những thông tin được cài đặt tròng file funtion.

Bạn thêm các file Js cũng tương tự nhưng bạn phải dùng hàm:

wp_register_script( string $handlestring|bool $srcarray $deps = array(),string|bool|null $ver = falsebool $in_footer = false )
wp_enqueue_script( string $handlestring $src = ''array $deps = array(),string|bool|null $ver = falsebool $in_footer = false )
để có thể nhúng file js vào.

Thêm Javascript vào wordpress

Ở thẻ Title trong phần head bạn có thể thêm câu lện WordPress sau để thay đổi tiêu để website

<title><?php wp_title(''); ?></title>
Và để tạo menu cho website thì bạn hãy làm như sau.

tạo menu wordpress

Lưu ý ở những chỗ mà có code HTML của menu bạn hãy chỉnh sửa lại theo đúng với cấu trúc menu của bạn là được.

Tiếp theo bạn hãy mở file footer.php ra để chỉnh sửa phần footer trang web.

phần footer

Sau đó hãy coppy phần footer từ template mẫu vào file footer này để tạo phần footer cho trang web của bạn

hoàn thành chân trang

Như vậy là bạn đã hoàn thành hai phần là đầu trang và chân trang đây chính là hai khu vực ít có sự thay đổi nhất trong toàn bộ website tiếp theo chúng ta hãy cùng làm phần thân trang đây chính là phần quan trọng cũng như phức tạp nhất của trang web.

Đầu tiên với trang index thì bạn hãy mở file ìndex,php ra để tạo phần thân trang cho trang chủ website của bạn.

Tại file này bạn hãy để lại hai hàm quan trọng là <?php get_header(); ?> và <?php get_footer(); ?> đây chính là hai hàm được dùng để gọi phần đầu và chân trang của bạn. Còn những phần còn lại nằm giữa hai hàm này bạn có thể xoá hết đi và chèn code thân trang template của bạn vào đó.

code phần thân index

Như vậy bạn đã dễ dàng tạo trang chủ cho website của mình rồi phải không nào tiếp theo chúng ta hãy cùng làm thêm các phần như category, post và page để hoàn chỉnh trang web của bạn nhé.

Tiếp theo chúng ta hãy cùng làm phần Category nhé. Đây là phần mà khi bạn nhấn vào một chuyên mục nào đó thì website sẽ hiện ra những bài thuộc chuyện mục đó cho bạn.

Đầu tiên hãy mở file archive.php ra đây chính là file sẽ được chạy khi bạn nhấn vào một category nào đó thì nó sẽ hiển thị những bài viết thuộc category đó.

Tạo trang category

Tiếp theo bạn hãy coppy code của trang category của template của bạn và paste vào đây như vậy bạn đã có một trang category rồi bạn chỉ cần phải chỉnh sửa một số thành phần sao cho phù hợp nữa là được.

Như mình đã làm ví dụ ở Template của mình bạn có thể làm tương tự là được.

<?php get_header(); ?>

            <!--================Blog Categorie Area =================-->

            <section class="blog_categorie_area">

            <div class="container">

                <div class="row">

                    <div class="col-lg-4">

                        <div class="categories_post">

                            <img src="<?php echo get_template_directory_uri().'/' ?>image/blog/cat-post/cat-post-3.jpg" alt="post">

                            <div class="categories_details">

                                <div class="categories_text">

                                    <a href="blog-details.html"><h5>Social Life</h5></a>

                                    <div class="border_line"></div>

                                    <p>Enjoy your social life together</p>

                                </div>

                            </div>

                        </div>

                    </div>

                    <div class="col-lg-4">

                        <div class="categories_post">

                            <img src="<?php echo get_template_directory_uri().'/' ?>image/blog/cat-post/cat-post-2.jpg" alt="post">

                            <div class="categories_details">

                                <div class="categories_text">

                                    <a href="blog-details.html"><h5>Politics</h5></a>

                                    <div class="border_line"></div>

                                    <p>Be a part of politics</p>

                                </div>

                            </div>

                        </div>

                    </div>

                    <div class="col-lg-4">

                        <div class="categories_post">

                            <img src="<?php echo get_template_directory_uri().'/' ?>image/blog/cat-post/cat-post-1.jpg" alt="post">

                            <div class="categories_details">

                                <div class="categories_text">

                                    <a href="blog-details.html"><h5>Food</h5></a>

                                    <div class="border_line"></div>

                                    <p>Let the food be finished</p>

                                </div>

                            </div>

                        </div>

                    </div>

                </div>

            </div>

        </section>

        <!--================Blog Categorie Area =================-->




        <!--================Blog Area =================-->

        <section class="blog_area">

            <div class="container">

                <div class="row">

                    <div class="col-lg-8">

                        <div class="blog_left_sidebar">

                        <?php if (have_posts()) : while (have_posts()) : the_post(); // kiểm tra xem có post thuộc category này không nếu có thì bắt đầu vòng lặp để lấy ra?>

                        <article class="row blog_item">

                               <div class="col-md-3">

                                   <div class="blog_info text-right">

                                        <div class="post_tag">

                                        <?php

                                            $id = get_the_ID(); // Lấy ID của post

                                            $category_detail=get_the_category($id);// Lấy thông tin category của post

                                            foreach($category_detail as $cd){

                                                echo '<a href="'.get_category_link($cd->cat_ID). '">'. $cd->cat_name .'</a>';// Hiển thị các category thuộc post

                                                }

                                            ?>

                                        </div>

                                        <ul class="blog_meta list_style">

                                            <li><a href="#"><?php the_author(); // Lấy tên tác giả ?><i class="lnr lnr-user"></i></a></li>

                                            <li><a href="#"><?php the_date() ?><i class="lnr lnr-calendar-full"></i></a></li>




                                        </ul>

                                    </div>

                               </div>

                                <div class="col-md-9">

                                    <div class="blog_post">

                                        <img src="<?php echo get_the_post_thumbnail_url($id, 100);// Lấy hình đại diện của bài viết ?>" alt=""/>

                                        <div class="blog_details">

                                            <a href="<?php the_permalink(); // lấy link bài viết?>"><h2><?php the_title();// Lấy tiêu đề bài viết ?></h2></a>

                                            <p><?php the_excerpt(); // Lấy phần trích dẫn bài viết?></p>

                                            <a href="<?php the_permalink(); ?>" class="view_btn button_hover">View More</a>

                                        </div>

                                    </div>

                                </div>

                            </article>

                        <?php endwhile; ?>

                        <?php else:?>

                        <?php endif;?>







                            <nav class="blog-pagination justify-content-center d-flex">

                              

                                <?php pagination_custom(); // tạo phần phân trang bạn có thể xem hàm này tại bài viết này https://tuandc.com/thu-thuat-wordpress/huong-dan-tao-custom-pagination-phan-trang-trong-wordpress.html?>

                            </nav>

                        </div>

                    </div>

                    <div class="col-lg-4">

                        <div class="blog_right_sidebar">

                            <aside class="single_sidebar_widget search_widget">

                                <div class="input-group">

                                <!-- Tạo form tìm kiếm -->

                                <form style="width:100%" action="https://tuandc.com" id="searchform" method="get"> 

                                    <input type="text" onfocus="if (this.value == 'Search') 

                                    {this.value = '';}" onblur="if (this.value == '') 

                                    {this.value = 'Search';}" id="s" name="s"  

                                    class="form-control" placeholder="Search Posts"/>

                                

                                </form>




                                </div><!-- /input-group -->

                                <div class="br"></div>

                            </aside>

                            <aside class="single_sidebar_widget author_widget">

                                <img class="author_img rounded-circle" src="<?php echo get_template_directory_uri().'/' ?>image/blog/author.png" alt="">

                                <h4>Charlie Barber</h4>

                                <p>Senior blog writer</p>

                                <div class="social_icon">

                                    <a href="#"><i class="fa fa-facebook"></i></a>

                                    <a href="#"><i class="fa fa-twitter"></i></a>

                                    <a href="#"><i class="fa fa-github"></i></a>

                                    <a href="#"><i class="fa fa-behance"></i></a>

                                </div>

                                <p>Boot camps have its supporters andit sdetractors. Some people do not understand why you should have to spend money on boot camp when you can get. Boot camps have itssuppor ters andits detractors.</p>

                                <div class="br"></div>

                            </aside>

                            <aside class="single_sidebar_widget popular_post_widget">

                                <h3 class="widget_title">Popular Posts</h3>

                                <?php if (have_posts()) : while (have_posts()) : the_post(); // kiểm tra xem có post thuộc category này không nếu có thì bắt đầu vòng lặp để lấy ra?>

                                <div class="media post_item">

                                    <img src="<?php echo get_the_post_thumbnail_url(get_the_ID()); ?>" alt="post">

                                    <div class="media-body">

                                        <a href="<?php the_permalink(); ?>"><h3><?php the_title();?></h3></a>

                                        <p><?php echo get_the_date('D. M. Y', get_the_ID()) ?></p>

                                    </div>

                                </div>

                                <?php endwhile; ?>

                                <?php endif;?>







                                <div class="br"></div>

                            </aside>

                            <aside class="single_sidebar_widget ads_widget">

                                <a href="#"><img class="img-fluid" src="<?php echo get_template_directory_uri().'/' ?>image/blog/add.jpg" alt=""></a>

                                <div class="br"></div>

                            </aside>

                            <aside class="single_sidebar_widget post_category_widget">

                                <h4 class="widget_title">Post Catgories</h4>

                                <ul class="list_style cat-list">

                                <?php

                                    $args = array(

                                        'type'      => 'post',

                                        'child_of'  => 0,

                                        'parent'    => ''

                                    );

                                    $categories = get_categories( $args );

                                    foreach ( $categories as $cate ) { ?>

                                        <li>

                                        <a href="<?php echo get_category_link($cate->cat_ID)?>" class="d-flex justify-content-between">

                                            <p><?php echo $cate->cat_name; ?></p>

                                        </a>

                                    </li>

                                <?php } ?>




                                                                                            

                                </ul>

                                <div class="br"></div>

                            </aside>

                            <aside class="single-sidebar-widget newsletter_widget">

                                <h4 class="widget_title">Newsletter</h4>

                                <p>

                                Here, I focus on a range of items and features that we use in life without

                                giving them a second thought.

                                </p>

                                <div class="form-group d-flex flex-row">

                                    <div class="input-group">

                                        <div class="input-group-prepend">

                                            <div class="input-group-text"><i class="fa fa-envelope" aria-hidden="true"></i></div>

                                        </div>

                                        <input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Enter email" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Enter email'">

                                    </div>

                                    <a href="#" class="bbtns">Subcribe</a>

                                </div>  

                                <p class="text-bottom">You can unsubscribe at any time</p>  

                                <div class="br"></div>                          

                            </aside>

                            <aside class="single-sidebar-widget tag_cloud_widget">

                                <h4 class="widget_title">Tag Clouds</h4>

                                <ul class="list_style">

                                <?php 

                                // Lấy danh sách các tag có trong trang web để tạo tag cloud.

                                    $tags = get_tags(array(

                                    'hide_empty' => false

                                    ));

                                    

                                    foreach ($tags as $tag) {

                                        $tag_link = get_tag_link( $tag->term_id );

                                    echo '<li><a href="'.$tag_link.'">' . $tag->name . '</a></li>';

                                    }

                                    

                                    ?>




                                </ul>

                            </aside>

                        </div>

                    </div>

                </div>

            </div>

        </section>

        <!--================Blog Area =================-->

<?php get_footer(); ?>

Như ví dụ trang WordPress của mình thì sau khi hoàn thành chỉnh sửa nó sẽ được như sau.

Sau khi tạo category

Như vậy là bạn đã có một trang category khá là đơn giản rồi đúng không nào tiếp theo ta hãy tạo trang hiển thị chi tiết cho từng post nhé.

Đầu tiên bạn hãy mở thư mục format ra đây là thư mục chứa các file php định dạng nội dung của bạn, chắc hẳn bạn đã biết WordPress hỗ trợ rất nhiều các định dạng nội dung khác nhau như post, gallery,… và bạn hoàn toàn có thể sáng tạo cách trình bày hiển thị nội dung cho từng loại định dạng bài viết và định dạng cơ bản nhất chính là post. Bạn hãy mở file format.php, đây chính là file sẽ xử lý hiển thị cho nội dung post của bạn.

Bạn hãy coppy và dán toàn bộ mã nguồn template của trang post vào file này và bạn hãy chỉnh sửa lại chút để có thể hiển thị một các hợp lý nhất.

Như mình làm ở ví dụ sau.

              <?php

              /*

                 * This is the default post format.

                 *

                 * So basically this is a regular post. if you don't want to use post formats,

                 * you can just copy ths stuff in here and replace the post format thing in

                 * single.php.

                 *

                 * The other formats are SUPER basic so you can style them as you like.

                 *

                 * Again, If you want to remove post formats, just delete the post-formats

                 * folder and replace the function below with the contents of the "format.php" file.

                */

              ?>

              <!--================Blog Area =================-->

        <section class="blog_area single-post-area">

            <div class="container">

                <div class="row">

                    <div class="col-lg-8 posts-list">

                        <div class="single-post row">

                        <?php

                                            $id = get_the_ID(); // Lấy ID của post

                                            // $category_detail=get_the_category($id);// Lấy thông tin category của post

                                            // foreach($category_detail as $cd){

                                            //  echo '<a href="'.get_category_link($cd->cat_ID). '">'. $cd->cat_name .'</a>';// Hiển thị các category thuộc post

                                            //  }

                                            ?>

                            <div class="col-lg-12">

                                <div class="feature-img">

                                    <img class="img-fluid" src="<?php echo get_the_post_thumbnail_url($id, 100)?>" alt="">

                                </div>                                  

                            </div>

                            <div class="col-lg-3  col-md-3">

                                <div class="blog_info text-right">




                                    <div class="post_tag">

                                    <?php

                                  $category_detail=get_the_category($id);// Lấy thông tin category của post

                                  foreach($category_detail as $cd){

                                    echo '<a href="'.get_category_link($cd->cat_ID). '">'. $cd->cat_name .'</a>';// Hiển thị các category thuộc post

                                    }

                                  ?>

                                    </div>

                                    <ul class="blog_meta list_style">

                                        <li><a href="#"><?php the_author(); ?><i class="lnr lnr-user"></i></a></li>

                                        <li><a href="#"><?php the_date(); ?><i class="lnr lnr-calendar-full"></i></a></li>




                                    </ul>

                                    <ul class="social-links">

                                        <li><a href="#"><i class="fa fa-facebook"></i></a></li>

                                        <li><a href="#"><i class="fa fa-twitter"></i></a></li>

                                    </ul>

                                </div>

                            </div>

                            <div class="col-lg-9 col-md-9 blog_details">

                                <h2><?php the_title(); ?></h2>

                                <p class="excert">

                                    <?php the_excerpt();// Lay phan tom tat bai viet ?>

                                </p>




                            </div>

                            <div class="col-lg-12">

                                <!-- <div class="quotes">

                                    MCSE boot camps have its supporters and its detractors. Some people do not understand why you should have to spend money on boot camp when you can get the MCSE study materials yourself at a fraction of the camp price. However, who has the willpower to actually sit through a self-imposed MCSE training.                                      

                                </div> -->

                                <div class="row">

                                    <?php the_content(); ?>                         

                                </div>

                            </div>

                        </div>

                        <div class="navigation-area">

                            <div class="row">

                                <div class="col-lg-6 col-md-6 col-12 nav-left flex-row d-flex justify-content-start align-items-center">

                                    <div class="thumb">

                                        <a href="#"><img class="img-fluid" src="image/blog/prev.jpg" alt=""></a>

                                    </div>

                                    <div class="arrow">

                                        <a href="#"><span class="lnr text-white lnr-arrow-left"></span></a>

                                    </div>

                                    <div class="detials">

                                        <p>Prev Post</p>

                                       <?php echo _rand_posts();// Chạy hàm lấy ngẫu nhiên bài viết trong file function ?>




                                    </div>

                                </div>

                                <div class="col-lg-6 col-md-6 col-12 nav-right flex-row d-flex justify-content-end align-items-center">

                                    <div class="detials">

                                        <p>Next Post</p>

                                        <?php echo _rand_posts();// Chạy hàm lấy ngẫu nhiên bài viết trong file function ?>

                                    </div>

                                    <div class="arrow">

                                        <a href="#"><span class="lnr text-white lnr-arrow-right"></span></a>

                                    </div>

                                    <div class="thumb">

                                        <a href="#"><img class="img-fluid" src="image/blog/next.jpg" alt=""></a>

                                    </div>                                      

                                </div>                                  

                            </div>

                        </div>

                        <div class="comments-area">

                            <h4><?php $comment_count = wp_count_comments( $id ); echo $comment_count->moderated; // Đếm số commnet có trong bài viết ?> Comments</h4>

                            <?php 

                            $args = array('cat' => 'home','post_type' => 'post');

                            $post_obj = new WP_Query($args);




                                //HIển thị comment

                                $comments = get_comments(array(

                                    'post_id' => $id,

                                    'number' => '2' ));

                                foreach($comments as $comment) {?>

                                    <div class="comment-list">

                                    <div class="single-comment justify-content-between d-flex">

                                        <div class="user justify-content-between d-flex">

                                            <div class="thumb">

                                                <img src="<?php echo get_template_directory_uri() ?>/image/blog/c1.jpg" alt="">

                                            </div>

                                            <div class="desc">

                                                <h5><a href="#"><?php echo comment_author( $comment->comment_ID ); ?></a></h5>

                                                <p class="date"><?php echo $comment->comment_date; ?> </p>

                                                <p class="comment">

                                                    <?php echo $comment->comment_content; // hiển thị nội dung bình luận?>

                                                </p>

                                            </div>

                                        </div>

                                        <div class="reply-btn">

                                               <a href="" class="btn-reply text-uppercase">reply</a> 

                                        </div>

                                    </div>

                              <?php  }

                            ?>                                      

                        </div>




                        <?php 

                        comment_form(); // hàm này sẽ gọi comment form từ file comments.php ?>

                    </div>




                </div>

            </div>

        </section>

        <!--================Blog Area =================-->

Bạn có thể làm tương tự vói các định dạng khác của post.

Cuối cùng để hoàn tất trang web của chúng ta thì có thể bạn sẽ cần phải tạo một số trang với mục đích khác nhau.
Đầu tiên bạn hãy tạo một file php tại thư mục gốc của theme nhé tên thì bạn có thể đặt tuỳ ý theo mục đích của mình.

tao file page

Bạn nhớ phải có dòng chú thích

/*

Template Name: Contact

*/
Trong file template page đó nhé nếu không thì wordpress sẽ không nhận ra file template của bạn đâu.

Viết code cho page template

Tiếp theo bạn chỉ việc coppy code của page template từ template của bạn vào đây nữa là xong như vậy là bạn đã tạo được một custom page rồi đấy.

hoàn thành trang web

Như vậy chỉ với vài bước đơn giản bạn đã có thể tự mình làm ra một trang web WordPress dễ dàng và đơn giản đúng không nào, chỉ với 5 giờ bạn có thể có một trang web WordPress là điều hoàn toàn có thể làm được.

Chúc các bạn may mắn khi tự mình tạo một trang web WordPress dễ dàng và chuyên nghiệp nhé, nếu có chỗ nào cần tham khảo bạn có thể tải mã nguồn bài mình vừa làm ở đây.

Sử dụng tham số để truy vấn với WP_Query trong WordPress

Trong bài viết này, mình sẽ chia sẻ với bạn một số cách để sử dụng WP_Query trong WordPress, giúp bạn nắm hiểu rõ hơn về các tham số đầu vào và giá trị đầu ra khi truy vấn.

Khi bạn viết theme hay lập trình Plugin, việc truy vấn sử dụng WP_Query trong WordPress là điều không thể tránh khỏi. Có những yêu cầu thiết kế website khó khăn, nhưng nếu nắm bắt được truy vấn WP_Query với các tham số đầu vào và giá trị đầu ra sẽ làm việc code trở nên dễ dàng hơn rất nhiều. Trong bài viết này, mình sẽ chia sẻ với bạn một số cách để sử dụng WP_Query trong WordPress, giúp bạn nắm hiểu rõ hơn về các tham số đầu vào và giá trị đầu ra khi truy vấn.

Cách sử dụng WP_Query trong WordPress

Trước khi bắt đầu vào tìm hiểu các tham số đầu vào và giá trị đầu ra, mình cần nắm rõ cách sử dụng của WP_Query, và để theo dõi kết quả xem câu query đó trả về những thứ gì bạn có thể dùng một plugin của WordPress để làm điều đó là plugin Debug Bar.

Lấy danh sách các bài viết bằng query

WP_Query là một lớp đối tượng được định nghĩa, hoạt động của nó liên quan đến việc truy vấn phức tạp từ các loại Post và Page (kể cả custom post type). Cú pháp của WP_Query như sau:

$query = new WP_Query( $args );

Trong đó:

  • $query: là biến đối tượng trả về.
  • $args: là một biến mảng chứa các tham số truy vấn.

Để kiểm tra có bài đăng nào trả về trong truy vấn không bạn sử dụng hàm $query->have_posts(). Giá trị trả về của hàm have_posts() là TRUE hoặc FALSE.

Ví dụ như sau:

<?php
  $the_query = new WP_Query( $args );
   if ( $the_query->have_posts() ) {
      // Có dữ liệu
   } else {
      // Không có dữ liệu
   }
?>

Dữ liệu trả về được sử dụng trong vòng lặp để lấy dữ liệu. Ví dụ như sau:

<?php
   $the_query = new WP_Query( $args );
   if ( $the_query->have_posts() ) {
      while ( $the_query->have_posts() ) : $the_query->the_post();
         //Hiển thị nội dung từ vòng lặp
      endwhile;
      wp_reset_postdata();
    } else {
      // Không có dữ liệu
    }
?>

Trong đó:

  • $the_query->the_post(): Trả về mảng chứa dữ liệu.
  • wp_reset_postdata(): Khi sử dụng $the_query->the_post(), bạn nên sử dụng để reset về dữ liệu truy vấn mặc định.

Tham số truy vấn trong WP_Query WordPress

Tham số truy vấn theo tác giả

Lấy các bài viết của một tác giá xác định

Khi sử dụng tham số “author”, kết quả trả về sẽ là các bài viết của 1 hoặc nhiều các tác giả được liêt kê trong tham số. Có nhiều dạng liệt kê như: ID, name, một mảng, hoặc loại bỏ tác giả đó ra khỏi truy vấn. Cụ thể như sau:

//Tham số truy vấn theo ID tác giả
$query = new WP_Query( array( 'author' => 123 ) );

//Tham số truy vấn theo tên tác giả
$query = new WP_Query( array( 'author_name' => 'rami' ) );

//Tham số truy vấn nhiều ID của các tác giả.
$query = new WP_Query( array( 'author' => '2,6,17,38' ) );

//Tham số truy vấn loại trừ đi ID của một tác giả.
$query = new WP_Query( array( 'author' => -12 ) );

//Tham số truy vấn nhiều tác giả, tương tự
$query = new WP_Query( array( 'author__in' => array( 2, 6 ) ) );

//Tham số loại trừ tác nhiều tác giả.
$query = new WP_Query( array( 'author__not_in' => array( 2, 6 ) ) );

Tham số truy vấn theo danh mục bài viết

Truy vấn các bài viết cùng chuyên mục

Để thực hiện lấy các bài viết trong danh mục, bạn sử dụng các tham số như ‘cat’, ‘category_name’,…. Các cách dùng cụ thể của các tham số như sau:

//Tham số lấy các bài viết trong danh mục có ID là 4
$query = new WP_Query( array( 'cat' => 4 ) );

//Tham số lấy các bài viết trong danh mục có tên là staff
$query = new WP_Query( array( 'category_name' => 'staff' ) );

//Tham số lấy các bài viết trong danh mục ID là 4 (tương tự)
$query = new WP_Query( array( 'category__in' => 4 ) );

//Tham số lấy tất cả bài viết của các danh mục có liệt kê ID
$query = new WP_Query( array( 'cat' => '2,6,17,38' ) );

//Tham số lấy tất cả bài viết của các danh mục có liệt kê tên
$query = new WP_Query( array( 'category_name' => 'staff,news' ) );

//Tham số lấy tất cả bài viết được nằm trong cả hai mục staff và news
$query = new WP_Query( array( 'category_name' => 'staff+news' ) );

//Tham số lấy các bài viết mà nó không nằm trong một trong các danh mục được liệt kê.
$query = new WP_Query( array( 'cat' => '-12,-34,-56' ) );

//Tham số lấy tất cả bài viết được nằm trong cả hai mục ID là 2 và 6
$query = new WP_Query( array( 'category__and' => array( 2, 6 ) ) );

//Tham số lấy tất cả bài viết được nằm một trong hai mục ID 2 và 6
$query = new WP_Query( array( 'category__in' => array( 2, 6 ) ) );

//Tham số lấy các bài viết mà nó không nằm trong một trong các danh mục được liệt kê.
$query = new WP_Query( array( 'category__not_in' => array( 2, 6 ) ) );

Tham số truy vấn theo Tags

Lấy các bài viết theo tag

Để truy vấn lấy danh sách các bài viết theo Tag cũng tương tự như danh mục, cũng có các tham số như sau:

//Tham số truy cấn theo tên tag
$query = new WP_Query( array( 'tag' => 'cooking' ) );

//Tham số truy vấn theo ID của tag
$query = new WP_Query( array( 'tag_id' => 13 ) );

//Tham số truy vấn hiển thị các bài viết trong các tag
$query = new WP_Query( array( 'tag' => 'bread,baking' ) );

//Tham số truy vấn hiển thị các bài viết nằm trong 3 tag cùng lúc
$query = new WP_Query( array( 'tag' => 'bread+baking+recipe' ) );

//Tham số truy vấn hiển thị các bài viết nằm trong 2 tag cùng lúc
$query = new WP_Query( array( 'tag__and' => array( 37, 47 ) ) );

//Tham số truy vấn hiển thị các bài viết trong các tag
$query = new WP_Query( array( 'tag__in' => array( 37, 47 ) ) );

//Tham số truy vấn hiển thị các bài viết không nằm trong các tag
$query = new WP_Query( array( 'tag__not_in' => array( 37, 47 ) ) );

Tham số truy vấn theo Taxonomy

Khi bạn cần lấy các bài viết theo phân loại bài viết thì bạn có thể sử dụng Query với các tham số sau để lấy được danh sách các bài viết.

Lấy các bài viết theo một Taxonomy cụ thể.

$args = array(
‘post_type’ => ‘post’,
‘tax_query’ => array(
array(
‘taxonomy’ => ‘people’,
‘field’ => ‘slug’,
‘terms’ => ‘bob’,
),
),
);
$query = new WP_Query( $args );

Lọc các bài viết với tham số AND

$args = array(
‘post_type’ => ‘post’,
‘tax_query’ => array(
‘relation’ => ‘AND’,
array(
‘taxonomy’ => ‘movie_genre’,
‘field’ => ‘slug’,
‘terms’ => array( ‘action’, ‘comedy’ ),
),
array(
‘taxonomy’ => ‘actor’,
‘field’ => ‘term_id’,
‘terms’ => array( 103, 115, 206 ),
‘operator’ => ‘NOT IN’,
),
),
);
$query = new WP_Query( $args );

Lọc các bài viết với tham số OR

$args = array(
‘post_type’ => ‘post’,
‘tax_query’ => array(
‘relation’ => ‘OR’,
array(
‘taxonomy’ => ‘category’,
‘field’ => ‘slug’,
‘terms’ => array( ‘quotes’ ),
),
array(
‘taxonomy’ => ‘post_format’,
‘field’ => ‘slug’,
‘terms’ => array( ‘post-format-quote’ ),
),
),
);
$query = new WP_Query( $args );

Lọc các bài viết với tham số OR và AND

$args = array(
‘post_type’ => ‘post’,
‘tax_query’ => array(
‘relation’ => ‘OR’,
array(
‘taxonomy’ => ‘category’,
‘field’ => ‘slug’,
‘terms’ => array( ‘quotes’ ),
),
array(
‘relation’ => ‘AND’,
array(
‘taxonomy’ => ‘post_format’,
‘field’ => ‘slug’,
‘terms’ => array( ‘post-format-quote’ ),
),
array(
‘taxonomy’ => ‘category’,
‘field’ => ‘slug’,
‘terms’ => array( ‘wisdom’ ),
),
),
),
);
$query = new WP_Query( $args );

Tham số truy vấn tìm kiếm (search)

Được sử dụng khi bạn muốn tìm kiếm một bài viết, tác giả,…..

Tìm kiếm bài viết

$query = new WP_Query( array( ‘s’ => ‘keyword’ ) );

Tham số truy vấn theo Post và Page

Lấy các bài viết theo post và page.

$query = new WP_Query( array( ‘p’ => 7 ) );
//for page, use: ‘page_id’=>7

$query = new WP_Query( array( ‘name’ => ‘about-my-life’ ) );
//for page, use: ‘pagename’=>’about-my-life’

$query = new WP_Query( array( ‘pagename’ => ‘contact_us/canada’ ) );

// Lấy danh sách bài viết trên trang sử dụng tham số pagename.

$query = new WP_Query( array( ‘post_parent’ => 93 ) );

// Lấy danh sách bài viết theo post sử dụng tham số post_parent.

$query = new WP_Query( array( ‘post_parent__in’ => array( 2, 5, 12, 14, 20 ) ) );

// Lấy danh sách bài viết theo các id post.

$query = new WP_Query( array( ‘post_type’ => ‘page’, ‘post__in’ => array( 2, 5, 12, 14, 20 ) ) );

//Lấy các bài viết theo danh sách bài viết với kiểu post là page và với id

$query = new WP_Query( array( ‘post_type’ => ‘post’, ‘post__not_in’ => array( 2, 5, 12, 14, 20 ) ) );

Lấy danh sách bài viết kiểu post ngoại trừ các post có id được liệt kê.

Tham số truy vấn Post và Page sử dụng mật khẩu

$query = new WP_Query( array( ‘has_password’ => true ) );

// Truy vấn có mật khẩu

$query = new WP_Query( array( ‘has_password’ => false ) );

//Truy vấn không mật khẩu

$query = new WP_Query( array( ‘has_password’ => null ) );

// Truy vân có mật khẩu là trống.

$query = new WP_Query( array( ‘post_password’ => ‘zxcvbn’ ) );

// Truy vấn post có mật khẩu cụ thể.

Tham số truy vấn loại post

//Truy vấn loại post là page.

$query = new WP_Query( array( ‘post_type’ => ‘page’ ) );

// Truy vấn loại post bất kỳ.

$query = new WP_Query( array( ‘post_type’ => ‘any’ ) );

// Truy vấn theo loại post xác định

$args = array(
‘post_type’ => array( ‘post’, ‘page’, ‘movie’, ‘book’ )
);
$query = new WP_Query( $args );

Tham số truy vấn bài viết theo trạng thái (Status)

Đây là các tham số để sử dụng khi cần lấy danh sách các bài viết theo trạng thái cái này thường sử dụng khi bạn code phần admin của WordPress hơn

publish,pending,draft,auto-draft, future, private, inherit, trash, any

$query = new WP_Query( array( ‘post_status’ => ‘draft’ ) );

$args = array(
‘post_status’ => array( ‘pending’, ‘draft’, ‘future’ )
);
$query = new WP_Query( $args );

$args = array(
‘post_status’ => ‘any’,
‘post_type’ => ‘attachment’
);
$query = new WP_Query( $args );

Tham số truy vấn bài viết theo bình luận

// Truy vấn bài viết theo số bình luận

$args = array(
‘post_type’ => ‘post’,
‘comment_count’ => 20,
)
);
$query = new WP_Query( $args );

// Truy vấn bài viết theo một khoảng số bình luận nào đó.

$args = array(
‘post_type’ => ‘post’,
‘comment_count’ => array(
array(
‘value’ => 25,
‘compare’ => ‘>=’,
),
)
);
$query = new WP_Query( $args );

Tham số truy vấn bài viết theo phân trang

// Truy vấn theo số post trên một trang

$query = new WP_Query( array( ‘posts_per_page’ => 3 ) );

$query = new WP_Query( array( ‘posts_per_page’ => -1 ) );

// Truy vấn không phân trang

$query = new WP_Query( array( ‘nopaging’ => true ) );

// Truy vấn theo số trang cụ thể

$query = new WP_Query( array( ‘offset’ => 3 ) );

// Truy vấn theo số trang cụ thể cũng như số post trên mỗi trang cụ thể.

$query = new WP_Query( array( ‘posts_per_page’ => 5, ‘offset’ => 3 ) );

$query = new WP_Query( array( ‘paged’ => get_query_var( ‘paged’ ) ) );

Trên Page tĩnh hoặc page template thì dùng đoạn sau

$paged = ( get_query_var(‘page’) ) ? get_query_var(‘page’) : 1;
$query = new WP_Query( array( ‘paged’ => $paged ) );

Tham số truy vấn bài viết theo thứ tự sắp xếp

Khi bạn muốn truy vấn các bài viết theo thứ tự sắp xếp theo điều kiện mà bạn mong muốn thì bạn có thể sử dụng các query sau.

$args = array(
‘orderby’ => ‘title’,
‘order’ => ‘DESC’,
);
$query = new WP_Query( $args );

$args = array(
‘orderby’ => ‘menu_order title’,
‘order’ => ‘DESC’,
);
$query = new WP_Query( $args );

$args = array(
‘orderby’ => ‘rand’,
‘posts_per_page’ => 1,

);
$query = new WP_Query( $args );

Show post phổ biến bằng comment

$args = array(
‘orderby’ => ‘comment_count’
);
$query = new WP_Query( $args );

Show post theo custon fields

$args = array(
‘post_type’ => ‘product’,
‘orderby’ => ‘meta_value_num’,
‘meta_key’ => ‘price’,
);
$query = new WP_Query( $args );

$args = array(
‘orderby’ => array( ‘title’ => ‘DESC’, ‘menu_order’ => ‘ASC’ )
);
$query = new WP_Query( $args );

$args = array(
‘orderby’ => array( ‘meta_value_num’ => ‘DESC’, ‘title’ => ‘ASC’ ),
‘meta_key’ => ‘age’
);
$query = new WP_Query( $args );

$args = array(
‘post_type’ => ‘my_custom_post_type’,
‘meta_key’ => ‘age’,
‘orderby’ => ‘meta_value_num’,
‘order’ => ‘ASC’,
‘meta_query’ => array(
array(
‘key’ => ‘age’,
‘value’ => array( 3, 4 ),
‘compare’ => ‘IN’,
),
),
);
$query = new WP_Query( $args );

$q = new WP_Query( array(
‘meta_query’ => array(
‘relation’ => ‘AND’,
‘state_clause’ => array(
‘key’ => ‘state’,
‘value’ => ‘Wisconsin’,
),
‘city_clause’ => array(
‘key’ => ‘city’,
‘compare’ => ‘EXISTS’,
),
),
‘orderby’ => array(
‘city_clause’ => ‘ASC’,
‘state_clause’ => ‘DESC’,
),
) );

Tham số truy vấn bài viết theo thời gian

Khi muốn truy vấn bài viết theo mốc thời gian mà bạn mong muốn.

$query = new WP_Query( ‘year=2012&monthnum=12&day=12’ );

$args = array(
‘date_query’ => array(
array(
‘year’ => 2012,
‘month’ => 12,
‘day’ => 12,
),
),
);
$query = new WP_Query( $args );

$today = getdate();
$query = new WP_Query( ‘year=’ . $today[‘year’] . ‘&monthnum=’ . $today[‘mon’] . ‘&day=’ . $today[‘mday’] );

$today = getdate();
$args = array(
‘date_query’ => array(
array(
‘year’ => $today[‘year’],
‘month’ => $today[‘mon’],
‘day’ => $today[‘mday’],
),
),
);
$query = new WP_Query( $args );

$week = date( ‘W’ );
$year = date( ‘Y’ );
$query = new WP_Query( ‘year=’ . $year . ‘&w=’ . $week );

$args = array(
‘date_query’ => array(
array(
‘year’ => date( ‘Y’ ),
‘week’ => date( ‘W’ ),
),
),
);
$query = new WP_Query( $args );

$args = array(
‘date_query’ => array(
array(
‘hour’ => 9,
‘compare’ => ‘>=’,
),
array(
‘hour’ => 17,
‘compare’ => ‘<=’,
),
array(
‘dayofweek’ => array( 2, 6 ),
‘compare’ => ‘BETWEEN’,
),
),
‘posts_per_page’ => -1,
);
$query = new WP_Query( $args );

$args = array(
‘date_query’ => array(
array(
‘after’ => ‘January 1st, 2013’,
‘before’ => array(
‘year’ => 2013,
‘month’ => 2,
‘day’ => 28,
),
‘inclusive’ => true,
),
),
‘posts_per_page’ => -1,
);
$query = new WP_Query( $args );

$args = array(
‘date_query’ => array(
array(
‘column’ => ‘post_date_gmt’,
‘before’ => ‘1 year ago’,
),
array(
‘column’ => ‘post_modified_gmt’,
‘after’ => ‘1 month ago’,
),
),
‘posts_per_page’ => -1,
);
$query = new WP_Query( $args );

Tham số truy vấn bài đăng bằng Custom Field

Bạn cũng có thể truy vấn để lấy các bài đăng bẳng Custom Field và với kiểu truy vấn này bạn vẫn có thể dùng các biểu thức logic.

$query = new WP_Query( array( ‘meta_key’ => ‘color’ ) );

$query = new WP_Query( array( ‘meta_value’ => ‘blue’ ) );

$args = array(
‘meta_key’ => ‘color’,
‘meta_value’ => ‘blue’
);
$query = new WP_Query( $args );

$args = array(
‘meta_key’ => ‘color’,
‘meta_value’ => ‘blue’,
‘meta_compare’ => ‘!=’
);
$query = new WP_Query( $args );

$args = array(
‘post_type’ => ‘post’,
‘meta_key’ => ‘number’,
‘meta_value_num’ => 10,
‘meta_compare’ => ‘<‘,
);
$query = new WP_Query( $args );

$args = array(
‘post_type’ => ‘event’,
‘meta_key’ => ‘event_date’,
‘meta_value’ => date( “Ymd” ), // change to how “event date” is stored
‘meta_compare’ => ‘>’,
);
$query = new WP_Query( $args );

$args = array(
‘meta_key’ => ‘price’,
‘meta_value’ => ’22’,
‘meta_compare’ => ‘<=’,
‘post_type’ => ‘product’
);
$query = new WP_Query( $args );

$args = array(
‘post_type’ => ‘product’,
‘meta_query’ => array(
array(
‘key’ => ‘color’,
‘value’ => ‘blue’,
‘compare’ => ‘NOT LIKE’,
),
),
);
$query = new WP_Query( $args );

$args = array(
‘post_type’ => ‘product’,
‘meta_query’ => array(
‘relation’ => ‘OR’,
array(
‘key’ => ‘color’,
‘value’ => ‘blue’,
‘compare’ => ‘NOT LIKE’,
),
array(
‘key’ => ‘price’,
‘value’ => array( 20, 100 ),
‘type’ => ‘numeric’,
‘compare’ => ‘BETWEEN’,
),
),
);
$query = new WP_Query( $args );

$args = array(
‘post_type’ => ‘product’,
‘meta_query’ => array(
‘relation’ => ‘OR’,
array(
‘key’ => ‘color’,
‘value’ => ‘orange’,
‘compare’ => ‘=’,
),
array(
‘relation’ => ‘AND’,
array(
‘key’ => ‘color’,
‘value’ => ‘red’,
‘compare’ => ‘=’,
),
array(
‘key’ => ‘size’,
‘value’ => ‘small’,
‘compare’ => ‘=’,
),
),
),
);
$query = new WP_Query( $args );

Tham số truy vấn bài đăng bằng quyền user

Khi bạn muốn hiển thị các bài đăng thuộc quyền của một user nào đó bạn có thể sử dụng query này để truy vấn bài đăng đó.

$args = array(
‘post_status’ => array( ‘publish’, ‘private’ ),
‘perm’ => ‘readable’,
);
$query = new WP_Query( $args );

Tích hợp tiện ích nhắn tin Facebook vào WordPress đơn giản

Trong bài viết này, mình sẽ chia sẻ với bạn cách để tích hợp tiện ích nhắn tin Facebook Messenger vào website để dễ dàng kết nối với khách hàng.

Facebook là một nền tảng mạng xã hội lớn với hàng trăm triệu người sử dụng hàng ngày. Ở Việt Nam, số người sử dụng Facebook chiếm hơn 1/3 dân số. Đối với dân marketing, Facebook là một trong những kênh quan trọng, nếu kết nối được người dùng ở các kênh khác với Facebook thì thật tuyệt vời. Trong bài viết này, mình sẽ chia sẻ với bạn cách để tích hợp tiện ích nhắn tin Facebook Messenger vào website để dễ dàng kết nối với khách hàng.

Lấy mã nhúng của trang Facebook

  • Lựa chọn một trang Facebook và truy cập vào mục cài đặt.

Truy cập vào mục cài đặt của Fanpage trên Facebook

  • Chọn “Nền tảng Messenger” nằm ở tab bên trái.

  • Kéo xuống dưới dùng và chọn “Thiết lập” trong phần “Plugin chat với khách hàng”/

  • Một bảng thiết lập hiển thị. Nhấn “Tiếp” để tiếp tục.

  • Thiết lập ngôn ngữ hiển thị và chỉnh sửa dòng chữ lời chào xuất hiện. Nhấn tiếp để sang bước hai.

  • Thiết lập thời gian sẽ phản hồi, và màu sắc chủ đạo. Nhấn tiếp để sang bước 3.

  • Thiết lập miền trang web và sao chép mã hoàn thành.

Như vậy là đã lấy được mã Facebook Messenger. Bạn sao chép hoặc dán mã này vào note để chuẩn bị chèn vào website. Mình khuyên các bạn không nên sử dụng các mã bên ngoài vì chúng chứa những thứ kém an toàn hoặc làm cho website của bạn trở nên chậm chạp hơn.

Chèn mã vào Website WordPress

Sau khi đã có được mã, bây giờ mình sẽ hướng dẫn các bạn cách chèn vào website WordPress. Một số theme có hỗ trợ phần chèn mã trong phần “tùy biến” hoặc widgets. Nếu đã có bạn chỉ cần truy cập vào mục Giao diện > Tùy biến, hoặc Giao diện > Widgets và tìm phần đó để chèn. Nếu không có bạn có thể chèn trực tiếp vào code như sau.

  • Tại menu bên trái trong trang quản trị của WordPress, bạn nhấn chọn Giao diện > Sửa.

  • Tại cột bên phải, bạn tìm đến file footer.php.

  • Dán đoạn mã đã copy vào đây và nhấn “Cập nhật tập tin” để lưu các thay đổi.

Chúc bạn thành công !

Vô hiệu hóa tự động update plugin trong WordPress

Trong bài viết này mình sẽ chia sẻ với bạn các cách để vô hiệu hóa việc cập nhật Plugin, themes, WordPress bằng nhiều cách.

WordPress là một trong những CMS phát triển mạnh. Mã nguồn, các theme và plugin của nó cũng liên tục được cập nhật phiên bản mới. Tuy nhiên trong một số trường hợp bạn không muốn cho cập nhật, ví dụ như phiên bản theme vẫn không hỗ trợ các Plugin mới. Do đó việc cập nhật không đồng bộ sẽ khiến website bạn bị hư. Trong bài viết này mình sẽ chia sẻ với bạn các cách để vô hiệu hóa việc cập nhật này.

Cấu hình vô hiệu hóa cập nhật Plugin và Theme

Nếu bạn muốn vô hiệu hóa toàn bộ cập nhật từ plugin đến theme, bạn có thể thêm đoạn mã sau vào tệp wp-config.php.

define('DISALLOW_FILE_MODS',true);

Chặn update cho plugin bất kỳ

Trong một số trường hợp, bạn chỉ muốn chặn update cho một vài plugin, vì bạn biết rõ nó sẽ không hỗ trợ cho theme của bạn nếu như update. Điều này khá đúng với các theme tự code.

Để chặn update một theme, bạn mở file functions.php và thêm vào đoạn code sau:

function disable_update_plugin( $value ) {
   unset( $value->response['woocommerce/woocommerce.php'] );
   return $value;
}
add_filter( 'site_transient_update_plugins', 'disable_update_plugin' );

Trong đó, phần “unset( $value->response[‘woocommerce/woocommerce.php’] );” bạn chú ý đây là phần bạn xác định plugin sẽ được chặn update. Bạn chỉ cần thay đổi dòng “woocommerce/woocommerce.php” theo đúng plugin của ban. Với “woocommerce” là thư mục chứa plugin và “woocommerce.php” là tệp php chính của Plugin.

Trước khi vô hiệu hóa update, WooCommerce phiên bản 3.4.7 của mình được yêu cầu cập nhật lên 3.5.2

Sau khi vô hiệu hóa, WooCommerce phiên bản cũ đã không còn thông báo update nữa.

Sử dụng plugin tùy chọn update

Nếu bạn không muốn can thiệp vào mã nguồn, bạn vẫn có thể chặn update cho theme, plugin và cả WordPress core. Bạn chỉ cần cài đặt plugin “Easy Updates Manager”.

Sau khi cài đặt và kích hoạt, bạn truy cập vào dashboard của plugin tại phần “Updates Options”. Chọn General để bật tắt update cho tất cả, chọn các mục thành phần như Plugins, Themes để bật tắt update chi tiết hơn.

WordPress 5.0 đã chính thức được cập nhật

Sáng ngày hôm nay mình đã nhận thông báo WordPress đã chính thức cho cập nhật. Bản WordPress mới này được xem là một bản có một số thay đổi đặt biệt quan trọng.

Sáng ngày hôm nay mình đã nhận thông báo WordPress đã chính thức cho cập nhật. Bản WordPress mới này được xem là một bản có một số thay đổi đặt biệt quan trọng. Cùng mình xem những gì mới trong bản cập nhật lần này nhé.

Thông báo cập nhật phiên bản WordPress 5.0 hiển thị trên website.

Sự thay đổi lớn về trình soạn thảo trong WordPress 5.0

Trình soạn thảo văn bản mới (Gutenberg) của WordPress 5.0 chính là trọng tâm của bản cập nhật lần này. Nếu bạn đã dùng quen các trình soạn thảo trước đây, thì có thể bạn sẽ cảm thấy rất khó chịu khi lần đầu sử dụng trình soạn thảo mới này.

Trình soạn thảo Gutenberg mới trên WordPress 5.0 chính là thành phần thay đổi quan trọng nhất

Tại trình soạn thảo mới này, bạn sẽ thấy một số tính năng mới mà phiên bản trước đây không có như: media & text, Inline Image, Cover, Galley, nhúng và Widgets,… Đây là điều mà mình thấy rất thú vị. Tuy nhiên việc nó hiển thị lên các theme như thế nào thì cùng mình thử nghiệm trên theme này nhé.

Đây là một block về media & text, sử dụng hình ảnh bên trái và chữ viết bên phải. Hình phía bên trái là hình ảnh được soạn trong trình soạn mới. và đây là kết quả bạn thấy trên theme.

 Đây là block Image Inline. Block này hỗ trợ tốt trong việc viết báo. Tuy nhiên nó vẫn chưa thật sự tốt và hấp dẫn lắm. và trong theme mình nó không hoạt động.

Đây là block Cover, block này khá thú vị và rất thú vị để làm nội dung. Thật tuyệt là theme mình vẫn áp dụng được block này.

Block dưới đây là block Galley, block này là một trong những block khá được trông chờ. Thật tuyệt khi nó hoạt động tốt trên theme của mình.

Block bên dưới là một block nhúng, mình đã nhúng 1 video từ Youtube. Thật sự thì nó vẫn không khác gì cách nhúng thông thường, nhưng nó giúp mình đỡ tốn kém thời gian hơn rất nhiều.

Và còn nhiều tính năng mới rất tuyệt vời để trải nghiệm và làm bài viết trở nên phong phú hơn.

Trình soạn thảo mới này của WordPress cho thấy khẩu hiệu “Freedom to Build, Freedom to Write” đã được làm khá tốt.

Trình soạn thảo mới làm Developer hạnh phúc hơn 🙂

WordPress 5.0 không chỉ cung cấp thêm nhiều công cụ cho các tác giả, mà các Developer cũng cảm thấy hạnh phúc hơn khi lập trình giao diện. 

Đầu tiên là nó sẽ bảo đảm được giao diện không bị phá vỡ. Với nhiều tính năng hơn, thì việc không can thiệp vào sâu trong mã nguồn sẽ đảm bảo được an toàn cho giao diện hơn.

Bạn sẽ không cần phải code quá nhiều để tạo ra một trang landing page nữa. Tất cả các khối có sẵn mới nãy sẽ hỗ trợ một cách nhanh chóng hơn.

Việc cung cấp đầy đủ các thành phần cần thiết cũng giúp developer tránh được việc yêu cầu phải cài thêm plugin, đảm bảo website hoạt động tốt hơn.

Cần thời gian để làm quen với trình soạn thảo mới trong WordPress 5.0

Nhiều người chắc hẵn sẽ chưa quen và muốn sử dụng trình soạn thảo cũ. Không sao bạn vẫn có thể sử dụng trình soạn thảo cũ khi nâng cấp lên WordPress 5.0 bằng cách cài đặt thêm Plugin Classic Editor. Hoặc sử dụng hai đoạn code sau trong file Functions.php

// disable for posts
add_filter('use_block_editor_for_post', '__return_false', 10);

// disable for post types
add_filter('use_block_editor_for_post_type', '__return_false', 10);

Chúc bạn vui vẻ với trình soạn thảo mới trong WordPress 5.0

Các cách chụp màn hình máy tính nhanh chóng và đơn giản nhất

Trong bài viết này mình sẽ chia sẻ với bạn các cách để chụp màn hình máy tính nhanh chóng và đơn giản nhất mà không còn phải cầm điện thoại hay máy ảnh để chụp nữa.

Máy tính vẫn có những điều ít ai biết, và một trong những điều không nhiều người biết đến đó là cách chụp màng hình máy tính. Trong bài viết này mình sẽ chia sẻ với bạn các cách để chụp màn hình máy tính nhanh chóng và đơn giản nhất mà không còn phải cầm điện thoại hay máy ảnh để chụp nữa.

Chụp màn hình máy tính không cần cài phần mềm

Mặc định bàn phím máy tính sẽ có một nút chức năng thường có các tên như: “Prnt Scrn”, “Print”, “PrtSc”,…. Sau khi nhấn nút này hình ảnh trên màng hình sẽ được chụp và lưu vào bộ nhớ tạm (trong một số máy laptop, bạn cần nhấn thêm nút chức năng “Fn”). Ở trên máy Mac của Apple, bạn cần nhấn tổ hợp phím command + shift + 3 để chụp màng hình.

Nút chức năng chụp màng hình trên bàn phím thường ở phí trên bên phải.

Trên Windown, sau khi chụp bạn có thể vào Word, trên Facebook,…. để Paste thẳng vào. Nếu bạn muốn cắt một phần của tâm hình bạn có thể sử dụng ứng dụng Paint có sẵn trong Windows, dán vào và bắt đầu chỉnh sửa.

Chụp màn hình máy tính chuyên nghiệp với phần mềm Snagit

Snagit là một phần mềm chụp hình và quay phim màng hình chuyên nghiệp của hãng Techsmith. Thao tác dễ dùng cùng hàng loạt các tính năng mạnh mẽ giúp bạn nhanh chóng có một tấm hình hoặc những thước phim quay màng hình máy tính cực kỳ chuyên nghiệp.

Những tính năng đặc biệt của Snagit 13 phiên bản mới

Sau khi cài đặt, Snagit cũng sử dụng các phím chụp hình trên bàn phím. Tuy nhiên thay vì chỉ lưu vào bộ nhớ tạm, Một thước ngắm hiển thị cho phép bạn khoan vùng chụp trước khi chụp, rút ngắn thời gian cắt lại.

Snagit cũng có thể nhận dạng ra các vùng và tự khoang vùng một cách chính sác

Sau khi đã chụp, một ứng dụng editor sẽ hiển thị, với nhiều công cụ, bạn có thể hoàn thành hình ảnh và xuất ra với nhiều định dạng.

Chụp màn hình máy tính khi không có nút chụp hình trên bàn phím

Những lúc gặp tình trạng bàn phím không có nút chụp thì bạn phải làm gì. Nếu bạn đã cài đặt phần mềm, Bạn có thể sử dụng nút Capture để tiến hành chụp. Ngoài ra bạn có thể sử dụng một bàn phím ảo có tên On-Screen Keyboard để chụp bằng chuột. Bạn chỉ cần vào search tìm từ khóa “On-Screen Keyboard” để mở ứng dụng.

Bàn phím ảo trên màng hình máy tính

Chuẩn hóa dữ liệu đầu vào và ra trong WordPress

Chuẩn hóa dữ liệu là quá trình làm “sạch” dữ liệu không liên quan đến loại cần chuẩn hóa. Ví dụ mình muốn chuẩn hóa một chuỗi ký tự nhập vào theo loại “Text” thì dữ liệu ban đầu có các mã HTML, Javascript,… sẽ được loại bỏ để cho ra một đoạn text chuẩn.

Dữ liệu đầu vào rất quan trọng đối với một website, nó có thể trở thành mối nguy hiểm đối với website của bạn nếu bạn không kiểm tra dữ liệu và chuẩn hóa  trước khi cho phép lưu trữ. Minh đã gặp trường hợp nhiều bạn nói rằng theme tự viết của bạn ấy kém an toàn và thường xuyên có dữ liệu lạ,… WordPress không phải là một CMS kém bảo mật, độ bảo mật của nó cũng xếp hạng tốt, tuy nhiên tốt đến đâu cũng là do cách dùng của người dùng và admin. Trong bài viết này mình sẽ chia sẻ với bạn cách để làm wordpress trở nên an toàn hơn bằng cách chuẩn hóa dữ liệu đầu vào.

Chuẩn hóa dữ liệu (sanitize) là gì?

Chuẩn hóa dữ liệu là quá trình làm “sạch” dữ liệu không liên quan đến loại cần chuẩn hóa. Ví dụ mình muốn chuẩn hóa một chuỗi ký tự nhập vào theo loại “Text” thì dữ liệu ban đầu có các mã HTML, Javascript,… sẽ được loại bỏ để cho ra một đoạn text chuẩn. Phương pháp chuẩn hóa không những giúp lưu trữ dữ liệu an toàn mà còn giúp tiết kiệm được dung lượng dư thừa do không phải lưu trữ nhiều ký tự không cần thiết.

Nếu dữ liệu ban đầu của bạn có quá nhiều và chưa được chuẩn hóa bạn có thể sử dụng phương pháp chuẩn hóa đầu ra (escape) để lấy dữ liệu ra an toàn mà không phá vỡ cấu trúc và hoạt động bình thường của website.

Dưới đây mình sẽ chia sẻ về cách sử dụng một số hàm chuẩn hóa đầu vào và ra của WordPress.

Các hàm chuẩn hóa dữ liệu đầu vào của WordPress

Mình thường sử dụng các hàm chuẩn hóa dữ liệu đầu vào khi thực hiện tạo Metabox, hoặc các form nhập liệu ở theme. Một số hàm thường dùng như sau:

  • sanitize_email($email): Hàm chuẩn hóa Email, với hàm này nó sẽ loại bỏ các ký tự ra hoặc ngoài cấu trúc của Email để lấy được một chuỗi Email hoàn chỉnh, ví dụ như sau:
<?php 
     $email = "admin@example.com!";  echo sanitize_email($email); 
     //Kết quả là admin@example.com.
?>
  • sanitize_file_name($name): Hàm chuẩn hóa tên file, thay thế khoảng trống thành dấu gạch ngan, loại bỏ các ký tự đặt biệt không được chấp nhận trong file. Ví dụ như sau:
<?php 
     $name = "ten file"; 
     echo sanitize_file_name($name); 
     //Kết quả là ten-file. 
?>
  • sanitize_html_class(): Hàm chuẩn hóa lớp html, hàm này có thể ít được dùng, ví dụ như sau:
<?php
     $post_class = sanitize_html_class( $post->post_title );
     echo '<div class="' . esc_attr( $post_class ) . '">';
?>
  • sanitize_key($key): Hàm lọc đưa ra chữ thường (không in hoa), số, gạch ngan và dấu gạch dưới, Ví dụ như sau:
<?php
     echo sanitize_key('Chào mừng bạn đến với WordPress 2018');
     //kết quả "chomngbnnviwordpress2018"
?>
  • sanitize_mime_type($mime_type): Hàm lọc tên của một tệp và đưa ra loại tên tệp phù hợp nhất, ví dụ:
<?php
     echo sanitize_mime_type('tep hinh anh.jpg');
     //Kết quả "tephinhanh.jpg"
?>
  • sanitize_text_field($str): Hàm giúp chuyển các ký tự “<“, loại bỏ các tab, khoản trống thừa và ngắt dòng.
<?php
     echo sanitize_text_field('<h1> Tieu đề bài viết </h1>');
     //Kết quả Tieu đề bài viết
?>
  • sanitize_title_for_query($title): Được sử dụng để truy vấn cơ sở dữ liệu cho một giá trị từ URL.
  • sanitize_title_with_dashes($title, $unused, $context = ‘display’): Giới hạn đầu ra thành các ký tự chữ và số, dấu gạch dưới (_) và dấu gạch ngang (-). Khoảng trắng trở thành dấu gạch ngang.
<?php
     echo sanitize_title_with_dashes("I'm in LOVE with WordPress!!!1");
     // Kết quả im-in-love-with-wordpress1
?>

và một số hàm khác bạn có thể tham khảo tại codex.wordpress.org.

Các hàm chuẩn hóa dữ liệu đầu ra của WordPress

Thật ra khi đã chuẩn hóa tốt đầu vào thì đầu ra không cần chuẩn hóa cũng được, thế nhưng đôi khi mọi thứ không thể suôn sẻ được nên chúng ta có thể sẽ có sai sót trong quá trình chuẩn hóa đầu vào. Vậy nên chuẩn hóa đầu ra cũng là một trong những cách làm được khuyến khích để giữ giao diện được an toàn hơn. Dưới đây là một số hàm chuẩn hóa dữ liệu đầu ra cơ bản trong WordPress.

  • esc_html(): Sử dụng hàm này để chuẩn hóa HTML trước khi hiển thị ra bên ngoài.
<?php
   echo esc_html($title);
?>
  • esc_url(): Sử dụng hàm này trước khi in ra một URL cho các thuộc tính src hay href cho các thẻ HTML.
<?php
   echo esc_url( $img_url );
?>
  • esc_js(): Sử dụng để chuẩn hóa mã các đoạn mã javascript.
<a href="#" onclick="<?php echo esc_js( $custom_js ); ?>">Click me</a>
  • esc_attr(): Hãy sử dụng hàm này trước khi bạn in ra bất kỳ một thứ gì đó vào các thuộc tính của thẻ HTML.
<div class="<?php echo esc_attr( $extra_ul_class ); ?>">
  • esc_textarea(): Giúp bạn mã hóa các đoạn văn bản trước khi nó được hiển thị trong thẻ textarea.
<textarea><?php echo esc_textarea( $content ); ?></textarea>

Ổ cứng SSD và HDD khác nhau như thế nào? Có nên sài SSD hay không?

Mặc dù đều có chung tính năng nhưng SSD và HDD thì lại có rất nhiều điểm khác biệt, từ cấu tạo, cách hoạt động cho đến hiệu năng. SSD là một dạng thiết bị mới hơn so với HDD, vậy liệu SSD có đáng dùng hay không?.

Ổ cứng là một thiết bị lưu trữ dữ liệu phổ biến không thể thiếu trong các loại máy vi tính, từ những chiếc laptop xách tay cho đến máy tính để bàn. SSD và HDD là hai dạng ổ cứng được sử dụng nhiều nhất trên thị trường. Mặc dù đều có chung tính năng nhưng SSD và HDD thì lại có rất nhiều điểm khác biệt, từ cấu tạo, cách hoạt động cho đến hiệu năng. SSD là một dạng thiết bị mới hơn so với HDD, và có nhiều ưu điểm vượt trội. Vậy liệu SSD có đáng dùng hay không?.

Cấu tạo, vận hành và hiệu năng của ổ cứng HDD

HDD (Hard Disk Drive – Ổ đĩa cứng) là một thiết bị lưu trữ dữ liệu trên bề mặt các tấm đĩa tròn được phủ các lớp từ tính được gọi là đĩa từ.

Bên trong một ổ cứng HDD tiêu biểu

Đĩa từ chứa các Track là các đường tròn đồng tâm nằm trên mặt đĩa (một số loại có cả trên và dưới mặt đĩa),  Các Track chứa rất nhiều các Sector và dữ liệu được chứa trên các Sector này. Theo chuẩn thì một Sector có dung lượng chứa vào khoản 512 byte.

Track và Sector trên ổ đĩa cứng HDD

Để đọc và ghi dữ liệu lên Sector, đầu đọc phải được di chuyển đến phần Sector còn trống để ghi, hoặc đến Sector có chứa dữ liệu cần lấy. Do đó mà tốc độ đọc ghi của dữ liệu trên HDD phụ thuộc vào tốc độ vòng quay của nó.

Nhược điểm của HDD là các phần cơ bên trong dễ bị rơ rã sau một thời gian dài sử dụng, xuất hiện nhiều khối hư hỏng (bad block) và làm việc không còn chính xác. Một điểm yếu nữa của HDD đó chính là sự phân mảnh dữ liệu khi các dữ liệu nằm rãi rác và không được sắp xếp trật tự trên các Sector cũng khiến tốc độ đọc ghi dữ liệu trên HDD bị giảm sút đáng kể.

Tuy nhiên HDD vẫn được sử dụng phổ biến bởi giá thành không cao và độ tin cậy ngày càng được nâng cao nhờ các công nghệ mới ra đời.

Cấu tạo, vận hành và hiệu năng của ổ cứng SSD

SSD (Solid State Drive – ổ cứng thể rắn hay ổ cứng điện tử) là một loại ổ cứng thế hệ mới được cấu tạo và vận hành một cách khác biệt so với HDD. Ổ cứng SSD không sử dụng các đĩa từ và hoạt động cơ học để vận hành, nó sử dụng các chất bán dẫn để lưu trữ dữ liệu.

Ổ cứng SSD không có sự hoạt động cơ học nào

Do không có hoạt động cơ học nên ổ cứng SSD được xem là bền hơn nhiều so với HDD. Không có hoạt động cơ đồng nghĩa với việc tiếng ồn cũng không có, tốc độ không phụ thuộc vào độ trễ cơ học. SSD có thể hoạt động ở một nguồn điện áp thấp hơn HDD do đó nó cũng tiêu tốn một nguồn năng lượng thấp hơn.

Mặc dù vậy nhưng SSD vẫn có tồn đọng một số khuyết điểm như: dung lượng ít hơn nhiều so với HDD, nhiệt độ tỏa ra của SSD lớn hơn nhiều so với HDD, độ bền đọc/ghi của SSD cũng kém hơn so với HDD. Theo các tài liệu thì dạng SSD MLC có thể đọc ghi tối đa khoảng 10.000 lần và 100.000 lần cho dạng SSD SLC.

Có nên dùng ổ SSD thay thế cho HDD?

Với những ưu điểm của SSD liệu chúng ta có nên chuyển hẳn HDD sang sử dụng SSD hay không ?. Mặc dù SSD có nhiều ưu điểm về tốc độ, nhiệt độ và độ ồn, nhưng nó lại được xem là kém bền hơn so với HDD, tỉ lệ lỗi ghi nhận cũng rất cao. SSD dùng lâu có nguy cơ “đột tử” rất cao dễ dàng làm bạn mất trắng dữ liệu mà không có cách nào cứu được.

Với nhiều bạn thì SSD có thể là sở thích vì tốc độ, nhưng đối với mình nó chỉ là ổ cứng chỉ đọc (Readonly), sở dĩ gọi như vậy vì hơn 4 chiếc máy tính mình đang sử dụng đều dùng SSD để lưu trữ các dữ liệu ít thay đổi, nhưng được lấy ra dùng thường xuyên, một số được dùng để lưu trữ hệ điều hành và các tệp đọc thường xuyên. Còn “gánh team” đọc ghi các công việc thường xuyên của mình vẫn dùng HDD.

SSD cũng là một thiết bị đáng dùng, nhưng nó chưa thật sự hoàn hảo để thay thế toàn bộ cho HDD, và sử dụng song song đó là phương pháp mình lựa chọn.

Hướng dẫn cách tạo form gửi Email bằng PHP sử dụng Gmail SMTP

Trong bài viết này mình sẽ chia sẻ với bạn cách để gửi Mail qua giao thức SMTP trong lập trình PHP một cách đơn giản nhất.

Kết nối với Email là một trong những phần phổ biến, xuất hiện trong nhiều website từ trước đến nay. SMTP là một giao thức gửi Email phổ biến, đây là một giao thức dễ dàng sử dụng và cấu hình. Trong bài viết này mình sẽ chia sẻ với bạn cách để gửi Mail qua giao thức SMTP của Gmail trong lập trình PHP một cách đơn giản nhất.

Xây dựng Form giao diện gửi Mail

Đầu tiên là xây dựng form HTML bao gồm các trường là Email gửi đến, tiêu đề thư và nội dung thư gửi. Dữ liệu trong Form sẽ được gửi tới file mail.php để xử lý.

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>DEMO GỬI EMAIL</title>
    <link href="style.css" rel="stylesheet">
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
    <script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
  </head>

  <body>
    <br />
    <div class="inner contact">
      <div class="contact-form">
        <h1 align="center">TUANDC</h1>
        <h2 align="center">Hướng dẫn cách tạo form gửi Email bằng PHP sử dụng Gmail SMTP</h2>
        <hr>
        <form action="mail.php" method="post">
          <div class="col-xs-12 wow animated slideInRight" data-wow-delay=".5s">
            <h3>Gửi Thử Email</h3>
            <input type="email" name="emainsend" required class="form" placeholder="Đến : Địa chỉ Email " />
            <input type="text" name="subject" required class="form" placeholder="Tiêu đề" />
            <textarea name="message" class="form textarea" placeholder="Nội dung"></textarea>
          </div>
          <button type="submit" id="submit" name="send" class="form-btn semibold">Gửi Mail</button>
          <div class="clear"></div>
        </form>
      </div>
    </div>
  </body>

</html>

Giao diện sau khi hoàn thành

Tạo tệp cấu hình, tiếp nhận và xử lý Email gửi đi

Để gửi Mail qua SMTP, mình cần dùng đến một thư viện PHPMailer. Bạn có thể tải thư viện đó tại đây: Tải về thư viện.

Tạo một tệp mới có tên mail.php, sao chép toàn bộ thư mục thư viện PHPMailer bỏ vào thư mục web. Trở lại file mail.php và thêm đoạn code sau:

require_once 'PHPMailer/PHPMailerAutoload.php';

Tiếp theo hãy thêm đoạn code sau:

if(isset($_POST['emainsend']))
{
  //#1
  $to_id = $_POST['emainsend'];
  $message = $_POST['message'];
  $subject = $_POST['subject'];

  //#2
  $mail = new PHPMailer;
  $mail->isSMTP();
  $mail->Host = 'Host của SMTP';
  $mail->Port = Số_cổng;
  $mail->SMTPSecure = 'tls';
  $mail->SMTPAuth = true;
  $mail->Username = 'Emain_của_bạn@gmail.com';
  $mail->Password = 'Mật_khẩu_của_bạn';
  $mail->FromName = "Demo Send Mail";

  //#3
  $mail->addAddress($to_id);
  $mail->Subject = $subject;
  $mail->msgHTML($message);

  //#4
  if (!$mail->send()) {
    $error = "Lỗi: " . $mail->ErrorInfo;
    echo '<p>'.$error.'</p>';
  }
  else {
    echo '<p>Đã gửi!</p>';
  }
}
else{
  echo '<p>Vui lòng nhập dữ liệu</p>';
}

#1: Lấy dữ liệu được gửi từ form.

#2: Cấu hình thông tin SMTP. Các thông tin cấu hình sẽ được lấy từ thông tin cấu hình trên Gmail SMTP (phần sau mình sẽ hướng dẫn lấy thông tin cấu hình đó).

#3: Gán dữ liệu vào các biến gửi Mail.

#4: Thực hiện gửi Mail và kiểm tra trạng thái.

Cách lấy thông tin SMTP của Gmail

Bây giờ mình sẽ tiến hành lấy thông tin SMTP của Gmail để thay lên thông tin cấu hình trong file mail.php. Đầu tiên bạn truy cập đến đường link sau: https://myaccount.google.com/. Sau đó nhấn “Đăng nhập vào Google”.

Tiếp theo bạn tìm đến phần “Xác minh 2 bước” nhấn vào dấu mũi tên để bật tính năng này.

Nhấn “Bắt đầu” để tiếp tục.

Nhấn “Bật” để bật xác minh 2 bước.

Bây giờ hãy truy cập đường dẫn : https://myaccount.google.com/security, và nhấn vào “Mật khẩu ứng dụng”.

Tại phần “Mật khẩu ứng dụng” nhấn chọn loại dịch vụ là “Thư, và “Máy tính dùng Windows”. Nhấn “Tạo” để tạo mật khẩu.

Như vậy mật khẩu đã được tạo, bạn lưu mật khẩu này lại để sử dụng cho cấu hình SMTP.

Cấu hình SMTP và gửi thử

Bây giờ mình tiến hành cấu hình SMTP dựa vào thông tin mật khẩu ứng dụng đã lấy như sau:

Với Email bạn sử dụng Email đã đăng nhập để tạo mật khẩu ứng dụng, và mật khẩu chính là mật khẩu ứng dụng bạn đã tạo.

Email nhận được trên trên điện thoại nhanh chóng.. Có một số lỗi về chữ, bạn có thể thêm dòng “accept-charset=”utf-8” vào form để khắc phục lỗi này.

Và đây là kết quả trả về trên trang sau khi nhấn gửi mail.

Bổ sung tính năng Ajax khi gửi Mail

Tại thẻ Form, bạn loại bỏ thuộc tính action và thêm vào một thuộc tính ID ví dụ: <form method="post" id="mail-form">. Và sau đó thêm đoạn Javascript như sau vào dưới form.

<script type="text/javascript">
  $(document).ready(function()
  { 
    var submit = $("button[type='submit']");
    submit.click(function()
    {
      var data = $('form#mail-form').serialize();
      $.ajax({
          type : 'POST', 
          url : 'mail.php',
          dataType:'html',
          data : data,
          success : function(data)
      { 
      if(data == 'success') 
      {
	alert('Đã Gửi mail thành công !');
      }else{
	alert('Gửi mail thất bại, vui lòng kiểm tra lại');
      }
    }
  });
  return false;
 });
});
</script>

Bây giờ bạn mở file mail.php tìm đến phần //#4, và thay đổi thành đoạn code như sau:

//#4
  if (!$mail->send()) {
    $error = "Lỗi: " . $mail->ErrorInfo;
    echo 'Failed';
  }
  else {
    echo 'success';
  }
}
else{
  echo 'No data';
}

Gửi mail thành công, bảng thông báo Alert hiển thị mà không phải tải lại trang. Khuyến cáo khi sử dụng Ajax bạn nên thêm khoản thời gian delay, thuộc tính disable cho nút gửi nhằm hạn chế việc gửi nhiều lần.

Bạn có thể tùy biến, thay vì sử dụng Alert thì có thể sử dụng nhiều phương thức thông báo khác. Chúc bạn thành công !