Tạo Ảnh AI Ngay Trong Media Library WordPress: Viết Plugin Image Generation Với AI Client Từ A Đến Z

Man hinh Media Library WordPress voi anh AI duoc tao tu plugin AI Client
Câu trả lời nhanh
WordPress AI Client tu ban 7.0 cho phep plugin sinh anh AI ma khong can tich hop SDK tung nha cung cap. Bai huong dan nay dung plugin them nut Generate Image vao Media Library: dung wp_ai_client_prompt() voi FileTypeEnum::inline(), kiem tra is_supported_for_image_generation() truoc khi hien UI, viet 2 REST endpoint rieng de sinh anh va luu attachment, build frontend bang @wordpress/scripts va test tren site that.

WordPress 7.0 trở lên đã có sẵn một PHP API tên AI Client, cho phép plugin gửi prompt đến các nhà cung cấp AI và nhận kết quả về mà không cần tự viết tích hợp từng bên. Hôm nay mình sẽ đi từng bước dựng một plugin nhỏ nhưng chạy thật: thêm nút Generate Image File vào Media Library, nhập mô tả, nhận ảnh AI tạo và lưu thành attachment như ảnh upload thường.

Tạo ảnh AI ngay trong Media Library WordPress
Plugin thêm nút Generate Image File vào Media Library WordPress

Mình đã chạy thử plugin này trên site test WordPress 7.1 của mình và cách triển khai khá sạch: phần “AI” thực sự chỉ chiếm vài chục dòng PHP, phần còn lại là REST API và media handling chuẩn WordPress. Nếu bạn đã đọc bài tích hợp AI vào plugin không cần SDK thì bài này là phần thực hành nâng cấp: sinh ảnh thay vì sinh text.

WordPress AI Client hoạt động thế nào?

Cốt lõi của AI Client là plugin của bạn không bao giờ nói chuyện trực tiếp với nhà cung cấp AI. Bạn chỉ mô tả thứ mình cần: text hay ảnh, định dạng xuất ra, tỷ lệ khung hình — và WordPress tự định tuyến yêu cầu đến một model phù hợp mà chủ site đã cấu hình trong màn hình Settings > Connectors. Chủ site chọn Anthropic, Google hay OpenAI, quản lý API key tập trung tại một chỗ, plugin không cần trang cấu hình riêng.

Điều này mang lại ba lợi ích thực tế: plugin portable giữa các provider (không có nhánh code riêng cho từng bên), chủ site toàn quyền kiểm soát chi phí, và khi có model mới thì plugin cũ tự được hưởng lợi mà không cần update.

Hàm wp_ai_client_prompt() dùng như thế nào?

Mọi tương tác đều bắt đầu bằng một dòng: wp_ai_client_prompt() trả về một Prompt Builder theo kiểu fluent, bạn nối chuỗi các method để mô tả yêu cầu:

$builder = wp_ai_client_prompt()
    ->with_text( 'Summarize the benefits of caching in WordPress' )
    ->using_temperature( 0.7 );

$result = $builder->generate_text_result();

Kết quả trả về là đối tượng GenerativeAiResult — serializable, chứa nội dung AI tạo kèm metadata về provider và model đã xử lý. Vì nó serializable nên bạn trả thẳng qua rest_ensure_response() mà không cần bóc tách thủ công. Với sinh ảnh, bạn gọi generate_image_result() thay vì generate_text_result().

Một điểm quan trọng: dùng using_model_preference() để khai báo model ưa thích — nhưng đó là preference, không phải yêu cầu bắt buộc. Nếu model đầu không có, AI Client tự fallback xuống model kế tiếp vẫn hỗ trợ capability bạn cần. Đừng bao giờ code cứng một model duy nhất, điều đó phá vỡ toàn bộ mục đích trừu tượng hóa của API này.

Kiểm tra hỗ trợ trước khi hiện nút bấm như thế nào?

Không phải site nào cũng cấu hình provider AI, và không phải provider nào cũng sinh được ảnh. Trước khi hiện UI, hãy gọi:

$is_available = wp_ai_client_prompt()
    ->with_text( 'test' )
    ->is_supported_for_image_generation();

Hàm này thuần deterministic — không tốn một cuộc gọi API nào, không tốn tiền. Nó chỉ đối chiếu cấu hình builder với capability mà các model khả dụng khai báo. Mình hay dùng chính check này để quyết định có enqueue script hay không, để nút “Generate Image” chỉ xuất hiện khi nó thật sự chạy được. Đây là thói quen mình cũng áp dụng khi viết plugin tích hợp AI từ A đến Z: gate mọi tính năng AI bằng support check.

Cấu trúc plugin gồm những file nào?

Plugin của mình đặt tên ai-client-imagegen, cấu trúc gọn như sau:

ai-client-imagegen/
├── plugin.php            # entry point, đăng ký hook
├── includes/
│   ├── prompt.php        # hàm dựng prompt builder dùng chung
│   ├── rest-api.php      # 2 endpoint REST
│   └── admin.php         # đăng ký + enqueue script
├── src/index.ts          # UI modal bên frontend
├── build/                # output sau khi build @wordpress/scripts
├── package.json
└── composer.json

File plugin.php khai báo header với Requires at least: 7.0, rồi chặn an toàn bằng function_exists( 'wp_ai_client_prompt' ) — nếu site không có AI Client thì plugin im lặng thoát, không fatal error.

Dựng prompt sinh ảnh ra sao?

Đây là phần lõi của tích hợp AI. Trong includes/prompt.php, mình viết một hàm trả về builder chứ không phải kết quả — đó là lựa chọn thiết kế có chủ đích, vì caller quyết định lúc nào thực thi prompt, và chính builder này được tái dùng cho support check:

<?php
use WordPress\AiClient\Files\Enums\FileTypeEnum;
use WordPress\AiClient\Files\Enums\MediaOrientationEnum;

function aicig_get_image_generation_prompt( string $prompt, string $orientation = '' ): WP_AI_Client_Prompt_Builder {
    $builder = wp_ai_client_prompt()
        ->with_text( $prompt )
        ->as_output_file_type( FileTypeEnum::inline() );

    if ( $orientation ) {
        $builder->as_output_media_orientation( MediaOrientationEnum::from( $orientation ) );
    }

    return $builder;
}

Vài chi tiết đáng chú ý: FileTypeEnum::inline() yêu cầu ảnh trả về dạng base64 — tiện để preview trong trình duyệt trước khi lưu. MediaOrientationEnum là gợi ý tỷ lệ khung hình (square, landscape, portrait), truyền tùy chọn. Và tuyệt đối không chỉ định provider hay model trong hàm này — AI Client lo phần định tuyến.

REST endpoint sinh ảnh viết thế nào?

Mình tách làm hai endpoint riêng thay vì gộp một: /generate-image để sinh ảnh xem trước, /upload-image để lưu vào Media Library sau khi người dùng duyệt. Lý do đơn giản: người dùng nên được xem ảnh trước khi cam kết lưu nó.

register_rest_route(
    'ai-client-imagegen/v1',
    '/generate-image',
    array(
        'methods'             => WP_REST_Server::CREATABLE,
        'callback'            => 'aicig_rest_generate_image',
        'permission_callback' => static function () {
            return current_user_can( 'upload_files' );
        },
        'args'                => array(
            'prompt'      => array( 'type' => 'string', 'required' => true ),
            'orientation' => array(
                'type'     => 'string',
                'required' => false,
                'enum'     => array( 'square', 'landscape', 'portrait' ),
            ),
        ),
    )
);

function aicig_rest_generate_image( WP_REST_Request $request ) {
    $builder = aicig_get_image_generation_prompt(
        $request->get_param( 'prompt' ),
        $request->get_param( 'orientation' ) ?? ''
    );

    return rest_ensure_response( $builder->generate_image_result() );
}

Như bạn thấy, callback cực ngắn vì GenerativeAiResult serialize trực tiếp thành JSON, còn lỗi thì generate_image_result() tự trả WP_Error mà REST API xử lý luôn. Endpoint upload thì decodes base64, ghi file bằng wp_upload_bits(), tạo attachment bằng wp_insert_attachment() rồi sinh metadata — hoàn toàn là media handling chuẩn WordPress, không có gì dính đến AI.

Enqueue script ở đâu và khi nào?

Phần admin chỉ enqueue script trên đúng màn hình Media Library, và chỉ khi mọi điều kiện đạt:

function aicig_enqueue_media_assets( string $hook_suffix ): void {
    if ( 'upload.php' !== $hook_suffix ) {
        return;
    }
    if ( ! current_user_can( 'upload_files' ) ) {
        return;
    }
    if ( ! aicig_get_image_generation_prompt( 'test' )->is_supported_for_image_generation() ) {
        return; // hoặc hiện admin notice trỏ đến Settings > Connectors
    }
    wp_enqueue_script( 'aicig-imagegen' );
}

Ba lớp check lần lượt: đúng màn hình, đúng capability (phải khớp capability của REST endpoint, nếu không bạn sẽ hiện UI cho tính năng mà API từ chối), và đúng hỗ trợ AI. Dùng lại đúng hàm aicig_get_image_generation_prompt() với text ‘test’ là đủ vì support check không đọc nội dung prompt.

Build và test plugin thế nào?

Frontend là TypeScript khoảng 600 dòng, dùng @wordpress/api-fetch gọi hai endpoint, hiện preview kèm attribution provider/model. Mình không dán cả 600 dòng vào đây — bạn lấy trực tiếp file src/index.ts từ repo GitHub wptrainingteam/ai-client-imagegen của Training Team. Sau đó:

npm install
npx wp-scripts build

Kích hoạt plugin, vào Settings > Connectors nối một provider có model sinh ảnh (OpenAI hoặc Google AI đều được), rồi mở Media Library — nút Generate Image File xuất hiện. Thử một prompt đơn giản, duyệt ảnh, nhấn lưu. Kiểm tra bằng WP-CLI: wp post list --post_type=attachment --field=ID --posts_per_page=5 để xác nhận attachment mới được tạo.

Mình rút ra được gì sau khi làm thật?

Điểm khiến mình thích nhất ở kiến trúc này: phần tích hợp AI thực sự rất nhỏ. Toàn bộ “magic” nằm ở một hàm dựng prompt và một hàm support check — phần còn lại là WordPress chuẩn mà dev nào cũng đã viết hàng trăm lần. Nếu bạn đang cân nhắc thêm tính năng AI vào plugin của mình, đây là mẫu hình đáng theo: mô tả what, để WordPress lo how. Hạn chế duy nhất mình gặp là bạn phụ thuộc vào việc chủ site chịu cấu hình connector — nên luôn có một admin notice dẫn họ đến đúng màn hình cài đặt. Với xu hướng AI được đưa sâu vào lõi WordPress như Abilities API hay các công cụ quản trị bằng MCP mình từng giới thiệu, AI Client chính là móng để bạn viết plugin “AI-native” mà không khóa người dùng vào một nhà cung cấp nào.

Thanh Tùng

Mình là Thanh Tùng. Bạn bè gọi mình là "bác sĩ máy tính" vì hễ máy nào có vấn đề là mình muốn mò vào xem sao. Mình viết hướng dẫn theo cách mà mình mong người khác đã viết cho mình ngày xưa — từng bước rõ ràng, không bỏ sót, và nói luôn cái gì hay bị lỗi. Ngoài giờ làm mình chơi guitar, nuôi mèo, và có một con VPS riêng dành riêng cho việc cài thử đủ thứ linh tinh.

Xem tất cả bài viết →

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *