Category: WordPress

  • wp_register_block_types_from_metadata_collection() คืออะไร?

    wp_register_block_types_from_metadata_collection() เป็นฟังก์ชันใหม่ที่ถูกเพิ่มเข้ามาใน WordPress 6.8 เพื่อช่วยให้นักพัฒนาสามารถลงทะเบียน Block Type หลายๆ ตัวพร้อมกันได้ในครั้งเดียว โดยการอ่านข้อมูลจากไฟล์ block.json ที่อยู่ในไดเรกทอรีที่กำหนด

    หัวใจหลักของฟังก์ชันนี้คือการลดความซ้ำซ้อนและเพิ่มประสิทธิภาพในการจัดการโค้ด แทนที่จะต้องเรียกใช้ฟังก์ชัน register_block_type() ซ้ำๆ กันสำหรับทุกบล็อกที่เราสร้าง ตอนนี้เราสามารถใช้ฟังก์ชันนี้เพียงครั้งเดียวเพื่อจัดการบล็อกทั้งหมดที่อยู่ในโฟลเดอร์เดียวกันได้เลย

    ทำไมถึงควรใช้ฟังก์ชันนี้?

    • โค้ดสะอาดและจัดการง่าย: ไม่ต้องเขียน register_block_type() หลายบรรทัด ทำให้ไฟล์ functions.php หรือไฟล์ปลั๊กอินหลักของคุณสั้นกระชับและอ่านง่ายขึ้น
    • ลดความผิดพลาด: ลดโอกาสที่จะลืมลงทะเบียนบล็อกบางตัวไปเมื่อคุณมีบล็อกจำนวนมาก
    • สะดวกในการพัฒนา: เมื่อต้องการเพิ่มบล็อกใหม่ คุณเพียงแค่สร้างโฟลเดอร์ใหม่พร้อมไฟล์ block.json ภายในไดเรกทอรีหลัก ฟังก์ชันนี้จะทำการลงทะเบียนให้โดยอัตโนมัติ ไม่ต้องกลับไปแก้ไขโค้ด PHP เพื่อเพิ่มการลงทะเบียนใหม่

    วิธีการใช้งานและตัวอย่างประกอบ

    สมมติว่าเรากำลังสร้างปลั๊กอินชื่อ “My Awesome Blocks” และต้องการสร้าง Custom Block 2 ตัวคือ “Team Member” และ “Testimonial”

    ขั้นตอนที่ 1: จัดโครงสร้างโฟลเดอร์

    ก่อนอื่น เราต้องจัดโครงสร้างโฟลเดอร์ของปลั๊กอินให้รองรับการทำงานของฟังก์ชันนี้ โครงสร้างที่แนะนำคือการมีไดเรกทอรีหลักสำหรับเก็บทุกบล็อก (เช่น blocks/) และภายในนั้นจะมีโฟลเดอร์ย่อยสำหรับแต่ละบล็อก

    โครงสร้างไฟล์ของปลั๊กอินจะเป็นแบบนี้:

    my-awesome-blocks/

    ├── my-awesome-blocks.php // <– ไฟล์หลักของปลั๊กอิน

    └── blocks/ // <– ไดเรกทอรีสำหรับเก็บทุกบล็อก

    ├── team-member/ // <– โฟลเดอร์ของบล็อกแรก
    │ ├── block.json // <– ไฟล์ metadata ของบล็อก
    │ ├── edit.js // … ไฟล์อื่นๆ ของบล็อก
    │ └── style.css

    └── testimonial/ // <– โฟลเดอร์ของบล็อกที่สอง
    ├── block.json // <– ไฟล์ metadata ของบล็อก
    ├── edit.js // … ไฟล์อื่นๆ ของบล็อก
    └── style.css

    ขั้นตอนที่ 2: สร้างไฟล์ block.json

    ในแต่ละโฟลเดอร์ของบล็อก (team-member/ และ testimonial/) เราจะต้องมีไฟล์ block.json ซึ่งเป็นไฟล์ที่เก็บข้อมูลสำคัญทั้งหมดของบล็อกนั้นๆ

    ไฟล์ blocks/team-member/block.json:

    {
      "$schema": "https://schemas.wp.org/trunk/block.json",
      "apiVersion": 3,
      "name": "my-awesome-blocks/team-member",
      "title": "Team Member",
      "category": "widgets",
      "icon": "admin-users",
      "description": "A block to display a team member's profile.",
      "editorScript": "file:./edit.js",
      "style": "file:./style.css"
    }

    ไฟล์ blocks/testimonial/block.json:

    {
      "$schema": "https://schemas.wp.org/trunk/block.json",
      "apiVersion": 3,
      "name": "my-awesome-blocks/testimonial",
      "title": "Testimonial",
      "category": "widgets",
      "icon": "format-quote",
      "description": "A block to display a customer testimonial.",
      "editorScript": "file:./edit.js",
      "style": "file:./style.css"
    }

    ขั้นตอนที่ 3: ใช้ wp_register_block_types_from_metadata_collection()

    ตอนนี้มาถึงขั้นตอนสำคัญ คือการเขียนโค้ด PHP ในไฟล์ปลั๊กอินหลัก (my-awesome-blocks.php) เพื่อเรียกใช้ฟังก์ชันนี้

    เราจะเพิ่มโค้ดนี้ลงไปในไฟล์ my-awesome-blocks.php:

    <?php
    /**
     * Plugin Name: My Awesome Blocks
     * Description: A plugin to demonstrate bulk block registration.
     * Version: 1.0
     * Author: Your Name
     */
    
    if ( ! defined( 'ABSPATH' ) ) {
        exit; // Exit if accessed directly.
    }
    
    /**
     * Register all blocks from the 'blocks' directory.
     */
    function my_awesome_blocks_register_all_blocks() {
        // ตรวจสอบว่าฟังก์ชัน wp_register_block_types_from_metadata_collection มีอยู่จริงหรือไม่
        // (เพื่อรองรับ WordPress เวอร์ชันเก่ากว่า 6.8)
        if ( function_exists( 'wp_register_block_types_from_metadata_collection' ) ) {
            // ทำการลงทะเบียนบล็อกทั้งหมดที่อยู่ในไดเรกทอรี 'blocks'
            // ฟังก์ชันจะสแกนหาโฟลเดอร์ย่อยที่มีไฟล์ block.json อยู่ข้างใน
            $result = wp_register_block_types_from_metadata_collection( __DIR__ . '/blocks' );
    
            // (Optional) สามารถตรวจสอบผลลัพธ์เพื่อดีบักได้
            if ( is_wp_error( $result ) ) {
                error_log( 'Error registering blocks: ' . $result->get_error_message() );
            }
        }
    }
    
    // Hook ฟังก์ชันของเราเข้ากับ 'init' action
    add_action( 'init', 'my_awesome_blocks_register_all_blocks' );

    คำอธิบายโค้ด

    1. add_action( 'init', ... ): เราทำการลงทะเบียนบล็อกบน init hook ซึ่งเป็นช่วงเวลาที่เหมาะสมที่สุดสำหรับการลงทะเบียน Post Type, Taxonomy และ Block Type ต่างๆ
    2. if ( function_exists( ... ) ): เป็นการปฏิบัติที่ดีในการตรวจสอบว่าฟังก์ชันที่เราจะเรียกใช้นั้นมีอยู่จริงหรือไม่ เพื่อป้องกันข้อผิดพลาด (Fatal Error) หากปลั๊กอินนี้ถูกเปิดใช้งานบน WordPress เวอร์ชันที่เก่ากว่า 6.8 ซึ่งยังไม่มีฟังก์ชันนี้
    3. wp_register_block_types_from_metadata_collection( __DIR__ . '/blocks' ): นี่คือส่วนสำคัญที่สุด
      • __DIR__ . '/blocks': เราส่ง path แบบเต็มไปยังไดเรกทอรี blocks/ ของเราเป็นพารามิเตอร์
      • ฟังก์ชันนี้จะเข้าไปในโฟลเดอร์ blocks/ แล้วสแกนหาโฟลเดอร์ย่อยทั้งหมด (team-member, testimonial)
      • จากนั้นจะมองหาไฟล์ block.json ในแต่ละโฟลเดอร์ย่อยนั้น แล้วทำการลงทะเบียนบล็อกให้โดยอัตโนมัติ เสมือนกับการที่เราเรียก register_block_type('path/to/team-member') และ register_block_type('path/to/testimonial') เองเลย

    เพียงเท่านี้ เมื่อคุณเปิดใช้งานปลั๊กอิน “My Awesome Blocks” ทั้งบล็อก “Team Member” และ “Testimonial” ก็จะพร้อมให้ใช้งานใน Block Editor ทันที และในอนาคตหากคุณต้องการเพิ่มบล็อก “Service Box” คุณก็แค่สร้างโฟลเดอร์ service-box พร้อมไฟล์ block.json ข้างใน โดยไม่ต้องแก้ไขไฟล์ my-awesome-blocks.php อีกเลย!

  • Enable Media Replace : Plugin WordPress สำหรับแทนที่ File ที่เคย Upload ไปแล้ว

    Enable Media Replace : Plugin WordPress สำหรับแทนที่ File ที่เคย Upload ไปแล้ว

    1 ในปัญหาที่ลูกค้าที่ทำเว็บไซต์ด้วย WordPress เจอ คืออยากจะอัพเดต File ที่เคย Upload ไป แต่ไม่อยากจะเปลี่ยน URL หรืออยากจะอัพเดตรูป แต่รูปนี้ใช้อยู่ในหลาย ๆ บทความ จะไปไล่อัพเดตในทุกบทความเลย ก็เสียเวลา

    ผมเลยมาแนะนำ Plugin ที่ใช้สำหรับอัพเดต File ที่เคย Upload ไปแล้ว ชื่อ Enable Media Replace

    Enable Media Replace : Plugin WordPress สำหรับแทนที่ File ที่เคย Upload ไปแล้ว

    หลังจากที่เราติดตั้ง และเปิดใช้งานตัว Plugin นี้แล้ว ในหน้าเดี่ยวของ File ต่าง ๆ ที่อยู่ใน Media จะมีหัวข้อ Replace Media ปรากฎขึ้นมา

    เมื่อเราเลือก Upload a new file แล้ว จะไปยังหน้าจัดการ File ดังรูป

    File ที่จะนำไปแทนที่นั้น ต้องมีนามสกุลเดียวกับ File เดิม เช่น default.jpg ก็ต้อง Upload File ที่มีนามสกุล jpg มาแทนที่ หลังจากเลือก File ที่จะนำไปแทนที่แล้ว

    • ตำแหน่งที่ 1 ให้เลือก Replace the file, use new file name and update all links
    • ตำแหน่งที่ 2 นั้นเราสามารถเลือกวันที่สำหรับตัว File ได้

    หลังจากกด Update ก็เสร็จสิ้น File ที่ Upload ไปก็แทนที่ File เดิมในทุกหน้าให้แล้วครับ

  • แก้ปัญหาการแทรก tag pใน widget เมื่อใช้ gutenberg

    แก้ปัญหาการแทรก tag pใน widget เมื่อใช้ gutenberg

    หลังจากที่ WordPress มีการอัพเดตเป็น Version 5.8 ได้มีการนำ block ของ gutenberg มาใช้งานกับ widget แทนรูปแบบเดิมที่เคยใช้มา

    แก้ปัญหาการแทรก tag pใน widget เมื่อใช้ gutenberg

    ทีนี้เราดันมาเจอปัญหาว่า เวลาใช้ block ที่เป็น shortcode มันจะแทรก tag p เข้ามาอัตโนมัติ แล้วตัว shortcode ที่เราสร้างขึ้น มันดันไปตีกับตัว tag p ที่มันแทรกเข้า ทำให้ code กลายเป็นแบบนี้

    <p>[shortcode]</p>

    เราเลยต้องหาวิธีเอามันออกไป โดยเราไปไล่ code ที่ file

    wp-includes/class-wp-block.php

    แล้วก็เจอ filter ตัวนี้

    $block_content = apply_filters( "render_block_{$this->name}", $block_content, $this->parsed_block );

    เมื่อไปค้นต่อ เจอลิงก์นี้

    โดยเรานำมาปรับใช้เป็น

    add_filter( "render_block_core/shortcode", 'custom_render_block_shortcode', 10, 2);
    function custom_render_block_shortcode( $block_content, $parsed_block ) {
      $array = array (
        '<p>[' => '[', 
        ']</p>' => ']'
      );
      $block_content = strtr($block_content, $array);
    
      return $block_content;
    }

  • WordPress เพิ่ม singular.php เป็น theme template ตัวใหม่

    WordPress เพิ่ม singular.php เป็น theme template ตัวใหม่

    สำหรับ WordPress เวอร์ชั่น 4.3 ที่กำลังจะมา ทางทีมพัฒนาได้เพิ่ม singular.php เข้ามาเป็น theme template ตัวใหม่ โดยหลายคนรู้จัก singular อยู่แล้วจาก is_singular() ซึ่งถ้าหน้าที่แสดงอยู่เป็นหน้าเดี่ยวของ post type ใดๆ จะส่งค่า true กลับมาให้

    ใน wp-includes/template-loader.php เพิ่ม code ดังนี้

    และใน เพิ่ม code ดังนี้

    โดยใช้สำหรับหน้าเดี่ยวโดยไม่สนใจว่าเป็น post type แบบไหน ลำดับจะอยู่หลังจาก single.php หรือ page.php หรือ หน้าเดี่ยวของ post type อื่นๆ

    singular.php ช่วยให้เราไม่ต้องคิดมากเวลาจะหาว่า หน้าเดี่ยวนี้เรียกจาก file ไหน single.php หรือเปล่า หรือจะเป็น page.php ใช้แค่ singular.php ตัวเดียวก็แทนที่ได้หมดแล้ว

  • เพิ่มสินค้าอัตโนมัติ กรณีสินค้านั้นมีหลายตัวเลือก : WooCommerce

    เพิ่มสินค้าอัตโนมัติ กรณีสินค้านั้นมีหลายตัวเลือก : WooCommerce

    ตามปรกติปุ่ม Add to cart ของ WooCommerce เองก็เพิ่มสินค้าให้อัตโนมัติอยู่แล้ว เพียงแต่ถ้าเมื่อไหร่สินค้านั้น มีหลายตัวเลือก หรือถ้าดูในหลังบ้านของ WooCommerce ก็คือ มีการตั้งค่า Variation ให้กับสินค้า ตัวอย่างเช่น สินค้า A มี 2 สี 2 ขนาด คือ สีแดง ขนาด 5ml, สีแดง ขนาด 30ml, สีเขียว ขนาด 5ml และสีเขียว ขนาด 30ml แบบนี้จะทำให้เมื่อเรากดปุ่ม Add to cart แล้ว ตัว WooCommerce จะพาเราไปยังหน้าของสินค้านั้น เพื่อให้เราเลือกก่อนว่า จะเอาสีไหน ขนาดไหน

    คราวนี้ได้โจทย์มาจากลูกค้าว่า อยากจะให้เมื่อคนซื้อมากดปุ่ม Add to cart แล้ว ระบบจะเพิ่มสินค้าเข้าตะกร้าสินค้าให้เองอัตโนมัติจำนวน 1 ชิ้น

    ซึ่งในหลังบ้านของ WooCommerce ในส่วนของ Product แต่ละชิ้นนั้น จะมีส่วนให้ตั้งค่า Default Variation ของสินค้าชิ้นนั้นๆ อยู่แล้ว เลยใช้ส่วนนี้มาต่อยอดปรับแต่งปุ่ม Add to cart ให้ทำงานแบบที่ลูกค้าต้องการได้

    ก่อนอื่นต้องทำความเข้าใจเรื่อง Template ของ WooCommerce ก่อน https://docs.woothemes.com/document/template-structure/ ไม่ขออธิบายนะครับ ไปอ่านดู

    โดยปุ่ม Add to cart จะมีอยู่ 2 ส่วนคือ ส่วนของหน้ารวมสินค้า กับส่วนของหน้ารายละเอียดสินค้า ซึ่งปุ่ม Add to cart ที่เราต้องการจะปรับคือ หน้ารวมของสินค้า โดย File ที่เราต้องทำการแก้ไข จะอยู่ใน path yourtheme/woocommerce/loop/add-to-cart.php (อันนี้ยึดหลักตาม WooCommerce 2.2.2) ซึ่งใน File จะเขียนไว้ดังนี้

    ผมเลยเพิ่มโค้ดเข้าไปเป็นแบบนี้

    โดยเช็คว่าสินค้านั้น มีตัวเลือกหรือเปล่า หลังจากนั้นมาเช็คว่ามีค่า Default ตั้งไว้มั้ย ส่วน form ที่ใช้ในการส่งค่าสำหรับเพิ่มสินค้าเข้าตะกร้านั้น นำมาจากปุ่ม Add to cart ของหน้ารายละเอียดสินค้า เพียงแต่เรากำหนดค่าของตัวเลือกลงไปเลย รวมถึงจำนวน 1 ชิ้นด้วย

    ถ้าเห็นว่าโค้ดส่วนไหนควรปรับเปลี่ยน คอมเม้นต์บอกกันได้เลยนะครับ

  • Query ในหน้านั้น เราจะเพิ่ม Parameter เข้าไปยังไง : WordPress

    Query ในหน้านั้น เราจะเพิ่ม Parameter เข้าไปยังไง : WordPress

    อันนี้ยกตัวอย่างจากที่เจอมาเลย คือในหน้า Archive อยากให้มันเรียงตามชื่อหัวข้อ ไม่ได้อยากให้มันเรียงตามวันที่ แค่เพิ่ม parameter orderby=title เข้าไปทำยังไง

    อย่างแรกก็ประกาศ global $query_string; เพื่อที่เราจะได้นำ $query_string มาใช้งาน โดยมันคือ ค่า parameter ที่ใช้ในการ query_posts() ของแต่ละหน้านั่นละ แต่เราเรียกมาเพื่อที่จะเพิ่มค่า parameter ที่เราต้องการเข้าไป ส่วนเราสามารถปรับแต่งการเรียกต่างๆ ได้จากหัวข้อนี้ query_posts