THAM KHẢO NHANH WORDPRESS
Themes, hooks, queries, REST API, custom post types
Cơ bản về Theme
File bắt buộc
| style.css | Header metadata của theme + styles |
| index.php | Template dự phòng (bắt buộc) |
| functions.php | Cấu hình theme, hooks, enqueue |
| screenshot.png | Ảnh xem trước theme (1200x900) |
Header style.css
/*
Theme Name: My Theme
Theme URI: https://example.com
Version: 1.0
Requires at least: 6.0
*/
Cấu hình functions.php
add_action('after_setup_theme', function() {
add_theme_support('title-tag');
add_theme_support('post-thumbnails');
add_theme_support('html5', ['search-form', 'gallery']);
register_nav_menus(['primary' => 'Main Nav']);
});
Hệ thống phân cấp Template
Template trang
| front-page.php | Trang đầu tĩnh |
| home.php | Danh sách bài đăng blog |
| single.php | Bài đăng đơn |
| page.php | Trang đơn |
| archive.php | Lưu trữ bài đăng (ngày, danh mục) |
| category.php | Lưu trữ danh mục |
| search.php | Kết quả tìm kiếm |
| 404.php | Không tìm thấy |
| index.php | Dự phòng cuối cùng |
Template Parts
get_header(); // header.php
get_footer(); // footer.php
get_sidebar(); // sidebar.php
get_template_part('parts/card'); // parts/card.php
get_template_part('parts/card', 'featured');
Thứ tự tra cứu (bài đăng đơn)
| 1 | single-{post_type}-{slug}.php |
| 2 | single-{post_type}.php |
| 3 | single.php |
| 4 | singular.php |
| 5 | index.php |
Loop
Loop tiêu chuẩn
Template Tags
| the_title() | Xuất tiêu đề bài đăng |
| the_content() | Xuất nội dung bài đăng |
| the_excerpt() | Xuất trích đoạn bài đăng |
| the_permalink() | Xuất URL bài đăng |
| the_post_thumbnail() | Xuất ảnh đặc trưng |
| the_date() | Xuất ngày đăng |
| the_author() | Xuất tên tác giả |
| the_category() | Xuất link danh mục |
Getters (trả về không xuất)
$title = get_the_title();
$url = get_permalink();
$id = get_the_ID();
$thumb = get_the_post_thumbnail_url(null, 'medium');
Custom Post Types
Đăng ký CPT
add_action('init', function() {
register_post_type('product', [
'labels' => ['name' => 'Products', 'singular_name' => 'Product'],
'public' => true,
'has_archive' => true,
'supports' => ['title', 'editor', 'thumbnail'],
]);
});
Phân loại tùy chỉnh
register_taxonomy('brand', 'product', [
'labels' => ['name' => 'Brands'],
'hierarchical' => true,
'rewrite' => ['slug' => 'brand'],
]);
Tùy chọn supports
| title | Trường tiêu đề bài đăng |
| editor | Trình soạn thảo nội dung |
| thumbnail | Ảnh đặc trưng |
| excerpt | Trường trích đoạn |
| custom-fields | Meta box trường tùy chỉnh |
| page-attributes | Thứ tự menu, cha |
| revisions | Lịch sử sửa đổi |
Hooks & Filters
Actions (thực hiện gì đó)
// Register a hook
add_action('wp_head', 'my_analytics', 20);
function my_analytics() {
echo '';
}
Filters (sửa đổi dữ liệu)
// Modify the excerpt length
add_filter('excerpt_length', fn() => 30);
// Append text to every post
add_filter('the_content', function($c) {
return is_single() ? $c . '
Thanks for reading!
' : $c;
});
Hooks chính
| init | WP đã khởi tạo; đăng ký CPT ở đây |
| wp_enqueue_scripts | Enqueue CSS/JS |
| wp_head | Xuất vào |
| wp_footer | Xuất trước |
| save_post | Sau khi lưu bài đăng |
| pre_get_posts | Sửa đổi query chính trước khi thực thi |
| the_content | Filter xuất nội dung bài đăng |
| the_title | Filter xuất tiêu đề bài đăng |
WP_Query
Query tùy chỉnh
$q = new WP_Query([
'post_type' => 'product',
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
]);
while ($q->have_posts()) : $q->the_post();
the_title('
', '
');
endwhile; wp_reset_postdata();
Tham số phổ biến
| post_type | post, page, hoặc kiểu tùy chỉnh |
| posts_per_page | Số kết quả (-1 cho tất cả) |
| category_name | Lọc theo slug danh mục |
| tag | Lọc theo slug tag |
| s | Từ khóa tìm kiếm |
| meta_key / meta_value | Lọc theo trường tùy chỉnh |
| tax_query | Lọc phân loại nâng cao |
| date_query | Lọc theo khoảng thời gian |
Sửa đổi Query chính
add_action('pre_get_posts', function($q) {
if (!is_admin() && $q->is_main_query() && is_home()) {
$q->set('posts_per_page', 5);
}
});
REST API
Endpoints tích hợp
| /wp-json/wp/v2/posts | Liệt kê / tạo bài đăng |
| /wp-json/wp/v2/posts/{id} | Lấy / cập nhật / xóa bài đăng |
| /wp-json/wp/v2/pages | Endpoint trang |
| /wp-json/wp/v2/categories | Endpoint danh mục |
| /wp-json/wp/v2/media | Thư viện media |
| /wp-json/wp/v2/users | Endpoint người dùng |
Endpoint tùy chỉnh
add_action('rest_api_init', function() {
register_rest_route('myplugin/v1', '/items', [
'methods' => 'GET',
'callback' => fn($req) => new WP_REST_Response(
get_posts(['post_type' => 'item', 'numberposts' => 20])
),
'permission_callback' => '__return_true',
]);
});
Fetch từ JavaScript
const res = await fetch('/wp-json/wp/v2/posts?per_page=5');
const posts = await res.json();
posts.forEach(p => console.log(p.title.rendered));
Hàm
Hàm bài đăng
| get_posts($args) | Lấy mảng bài đăng |
| wp_insert_post($arr) | Tạo hoặc cập nhật bài đăng |
| wp_delete_post($id) | Đưa vào thùng rác hoặc xóa bài đăng |
| get_post_meta($id, $key) | Lấy giá trị trường tùy chỉnh |
| update_post_meta($id, $k, $v) | Thiết lập giá trị trường tùy chỉnh |
Người dùng & Xác thực
| wp_get_current_user() | Người dùng đang đăng nhập |
| is_user_logged_in() | Kiểm tra trạng thái đăng nhập |
| current_user_can($cap) | Kiểm tra quyền |
| wp_create_nonce($action) | Tạo nonce bảo mật |
| wp_verify_nonce($nonce, $a) | Xác thực nonce |
Hàm tiện ích
| esc_html($str) | Escape trong ngữ cảnh HTML |
| esc_attr($str) | Escape trong ngữ cảnh thuộc tính |
| esc_url($url) | Làm sạch URL |
| wp_kses_post($html) | Chỉ cho phép HTML an toàn trong bài đăng |
| sanitize_text_field($s) | Xóa thẻ và khoảng trắng dư thừa |
| absint($val) | Số nguyên tuyệt đối |
Enqueue
Enqueue Styles & Scripts
add_action('wp_enqueue_scripts', function() {
wp_enqueue_style('theme-style', get_stylesheet_uri(), [], '1.0');
wp_enqueue_script('theme-js', get_theme_file_uri('/js/app.js'),
['jquery'], '1.0', true);
});
Hàm Enqueue
| wp_enqueue_style($h, $src) | Đăng ký và enqueue CSS |
| wp_enqueue_script($h, $src) | Đăng ký và enqueue JS |
| wp_localize_script($h, $n, $d) | Truyền dữ liệu PHP sang JS |
| wp_dequeue_style($handle) | Xóa style đã enqueue |
| wp_dequeue_script($handle) | Xóa script đã enqueue |
Truyền dữ liệu sang JavaScript
wp_enqueue_script('my-app', get_theme_file_uri('/js/app.js'));
wp_localize_script('my-app', 'myData', [
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('my_action'),
]);
// JS: console.log(myData.ajaxUrl)
Các mẫu thường dùng
Template trang tùy chỉnh
AJAX Handler
add_action('wp_ajax_my_action', 'handle_my_action');
add_action('wp_ajax_nopriv_my_action', 'handle_my_action');
function handle_my_action() {
check_ajax_referer('my_action', 'nonce');
wp_send_json_success(['msg' => 'OK']);
}
Shortcodes
add_shortcode('greeting', function($atts) {
$a = shortcode_atts(['name' => 'World'], $atts);
return '
Hello, ' . esc_html($a['name']) . '!
';
});
// Usage: [greeting name="Zhi"]