Nội dung bài viết

Một trong những lỗi phổ biến nhất khi mới viết plugin hoặc theme WordPress là tự nối chuỗi đường dẫn. Kiểu như thế này:

// Đừng làm thế này
include '/home/user/public_html/wp-content/plugins/my-plugin/inc/helper.php';

Code đó chạy được trên máy bạn và hỏng ngay khi đưa lên server khác. WordPress có sẵn một bộ hàm để lấy đường dẫn, và việc đầu tiên cần nắm là phân biệt hai loại đường dẫn hoàn toàn khác nhau.

Đường dẫn vật lý và đường dẫn URL

Đường dẫn vật lý (path) là vị trí file trên ổ đĩa của server, ví dụ /var/www/html/wp-content/plugins/my-plugin/. Dùng nó khi bạn thao tác với file bằng PHP: include, require, file_get_contents, fopen.

Đường dẫn URL là địa chỉ trình duyệt truy cập được, ví dụ https://example.com/wp-content/plugins/my-plugin/. Dùng nó khi bạn nhúng tài nguyên vào trang: file CSS, JavaScript, hình ảnh.

Nhầm lẫn hai loại này là nguyên nhân của rất nhiều lỗi khó hiểu. Nhúng đường dẫn vật lý vào thẻ <img> thì ảnh không bao giờ hiện, còn include một URL thì hoặc lỗi hoặc mở ra lỗ hổng bảo mật nghiêm trọng.

Bảng tra nhanh

HàmTrả vềVí dụ kết quả
ABSPATHPath gốc WordPress/var/www/html/
plugin_dir_path( __FILE__ )Path thư mục plugin hiện tại/var/www/html/wp-content/plugins/my-plugin/
plugin_dir_url( __FILE__ )URL thư mục plugin hiện tạihttps://example.com/wp-content/plugins/my-plugin/
plugins_url()URL thư mục /pluginshttps://example.com/wp-content/plugins
get_template_directory()Path theme cha/var/www/html/wp-content/themes/parent/
get_stylesheet_directory()Path theme đang dùng (child nếu có)/var/www/html/wp-content/themes/child/
get_stylesheet_directory_uri()URL theme đang dùnghttps://example.com/wp-content/themes/child
content_url()URL thư mục /wp-contenthttps://example.com/wp-content
includes_url()URL thư mục /wp-includeshttps://example.com/wp-includes
admin_url()URL khu vực quản trịhttps://example.com/wp-admin/
site_url()URL nơi cài WordPresshttps://example.com
home_url()URL trang chủhttps://example.com
wp_upload_dir()Mảng chứa cả path lẫn URL thư mục uploadsxem bên dưới

Dùng trong plugin

Trong file plugin chính, cách chuẩn là định nghĩa hằng số một lần rồi tái sử dụng:

<?php
define( 'MY_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
define( 'MY_PLUGIN_URL',  plugin_dir_url( __FILE__ ) );

// Nạp file PHP: dùng PATH
require_once MY_PLUGIN_PATH . 'includes/class-loader.php';

// Nhúng tài nguyên: dùng URL
function my_plugin_assets() {
    wp_enqueue_style( 'my-plugin', MY_PLUGIN_URL . 'assets/style.css', [], '1.0.0' );
    wp_enqueue_script( 'my-plugin', MY_PLUGIN_URL . 'assets/app.js', [ 'jquery' ], '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'my_plugin_assets' );

__FILE__ là hằng số của PHP trỏ tới chính file đang chạy, nên hai hàm trên luôn cho ra kết quả đúng dù plugin được đặt ở đâu.

Dùng trong theme

Với theme, điều quan trọng là phân biệt theme cha và theme con:

// Luôn trỏ về theme CHA, kể cả khi đang chạy child theme
get_template_directory();
get_template_directory_uri();

// Trỏ về theme ĐANG kích hoạt (child nếu có, ngược lại là cha)
get_stylesheet_directory();
get_stylesheet_directory_uri();

Quy tắc thực dụng: khi viết code trong child theme mà muốn tham chiếu file của chính child theme, dùng get_stylesheet_directory(). Khi muốn tham chiếu file của theme cha, dùng get_template_directory().

Thư mục uploads

wp_upload_dir() trả về một mảng thay vì một chuỗi:

$upload = wp_upload_dir();

echo $upload['basedir']; // /var/www/html/wp-content/uploads
echo $upload['baseurl']; // https://example.com/wp-content/uploads
echo $upload['path'];    // .../uploads/2026/09  (thư mục theo tháng hiện tại)
echo $upload['url'];     // .../uploads/2026/09

Đừng bao giờ giả định thư mục uploads nằm ở wp-content/uploads, vì nó có thể được đổi chỗ qua cấu hình.

site_url() hay home_url()

Hai hàm này thường trả về cùng một giá trị nên nhiều người dùng lẫn lộn. Chúng chỉ khác nhau khi bạn cài WordPress trong một thư mục con nhưng muốn site chạy ở tên miền gốc:

  • site_url() trả về https://example.com/wordpress (nơi chứa mã nguồn)
  • home_url() trả về https://example.com (địa chỉ người dùng thấy)

Nguyên tắc: cần link cho người dùng thì dùng home_url(), cần trỏ tới file lõi WordPress thì dùng site_url().

Một lưu ý nhỏ về escape

Các hàm trả về URL không tự escape. Khi in ra HTML, hãy bọc lại cho an toàn:

<img src="<?php echo esc_url( MY_PLUGIN_URL . 'assets/logo.png' ); ?>" alt="Logo">