ตัวอย่าง การสร้าง Child theme ของ twentyfourteen
style.css
/* Theme Name: Twenty Fourteen Child Theme Description: This is a child theme for Twenty Fourteen Author: Brad Dalton Author URI: http://wpsites.net/ Template: twentyfourteen Version: 1.0 */ .entry-title { font-size: 50px; font-weight: 300; line-height: 1.09091; margin: 0 0 12px; text-transform: uppercase; } .entry-title a { color: red; }
functions.php
<?php add_action( 'wp_enqueue_scripts', 'wpsites_load_parent_styles'); function wpsites_load_parent_styles() { wp_enqueue_style( 'parent-styles', get_template_directory_uri().'/style.css' ); }
เสร็จแล้ว!! ง่ายมั๊ย
กฏ
1. Child theme ต้องมีอย่างน้อย 2 ไฟล์ คือ style.css และ functions.php
2. เอา2ไฟล์ ใส่ใน folder
3. folder ตั้งชื่ออะไรก็ได้
4. ถ้าสร้างไฟล์ใหม่ ธีมลูก จะใช้ไฟล์นั้นแทน ธีมหลัก เช่น ถ้าสร้าง index.php มันจะใช้ไฟล์นี้แทน index.php ในธีมหลัก
5. หากต้องการเพิ่ม code ใน style.css และให้ใช้งานได้ ต้องปรับเปลี่ยน code ของ functions.php ก่อน (ตัวอย่างด้านล่าง) โดยมันจะอ่าน style.css ของธีมลูกก่อน แล้วตามด้วย style.css ของธีมแม่ (ใช้ทั้งสองและเอามารวมกัน ทับส่วนที่ต่างกันเข้ามา)
6. functions.php (ใช้ทั้งสองและเอามารวมกัน ทับส่วนที่ต่างกันเข้ามา)
อธิบาย
ธีมลูก (Child Theme) คือ ธีมที่มีฟังก์ชั่นการใช้งานที่ได้มาจากธีมแม่ (Parent Theme)
การสร้างธีมลูก เพื่อสะดวกการปรับเปลี่ยนแก้ไขธีมที่ใช้อยู่
เหตุผลการใช้ Child Theme
– การปรับแต่ง Parent Theme โดยตรง เมื่อธีมอัพเดท จะถูกเขียนทับ
– พัฒนาธีมได้ง่ายและเร็ว และ อาจจะทำเป็นหลายเวอร์ชั่นก็ได้
wp_enqueue_style
คือ ฟังก์ชั่นเวิร์ดเพรส ที่ดึงไฟล์ style.css ของธีมหลักมาใช้
ฟังก์ชั่นนี้จะเหมาะสมในกรณีที่ธีมหลัก (Parent Theme) มีไฟล์ style.css เพียงไฟล์เดียว
หากมีหลายไฟล์เราจะต้องทำการทำการดึงมาทั้งหมด
<?php add_action( 'wp_enqueue_scripts', 'themevilles_enqueue_styles' ); function themevilles_enqueue_styles() { wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' ); } ?>
หาก ต้องการใช้งาน style.css ใน Child Theme ที่แตกต่างจากธีมหลัก ให้เขียนโค๊ดเพิ่ม
โดยต้องลำดับการเรียกไฟล์ให้ไปเรียกที่ธีมหลักก่อน แล้วตามด้วยธีมลูก ตามลำดับ
การระบุเวอร์ชั่นในธีมลูก เพื่อป้องกัน Cache ที่จะเกิดขึ้น
การเพิ่ม code ใน style.css ของธีมลูก ให้ปรับเปลียน code ใน functions.php เป็นดังนี้
<?php function themevilles_enqueue_styles() { $parent_style = 'parent-style'; wp_enqueue_style( $parent_style, get_template_directory_uri() . '/style.css' ); wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array( $parent_style ), wp_get_theme()->get('Version') ); } add_action( 'wp_enqueue_scripts', 'themevilles_enqueue_styles' ); ?>
สร้าง screenshot.png ให้มีขนาด 1200×900 pixel เมื่อแสดงผลจะลดขนาดเหลือ 387×290 pixel อัตโนมัติ
ธีมลูก สามารถแก้ไขได้ใน 3 ลักษณะ
– แก้ไฟล์ style.css (เมื่อ WordPress อ่านค่าจะใช้ค่าไฟล์ที่ธีมลูกก่อนทุกครั้ง แล้วค่อยไปอ่านธีมหลัก)
– แก้ไฟล์หลัก เช่น header.php, footer.php ต่างๆ
– แก้ไฟล์ functions.php
การแก้ไขไฟล์หลัก เราสามารถสร้างไฟล์ใหม่ โดยให้อยู่ในโฟลเดอร์ของธีมลูก
ในธีมหลัก (Parent Theme) มีไฟล์ header.php ในธีมลูกก็จะต้องมีไฟล์นี้เช่นเดียวกัน
หากเราต้องการแก้ไขในบางส่วนของไฟล์ ให้ copy จากไฟล์หลักมาใส่แล้วทำการแก้ไขนะจุดนั้นๆ เพียงเท่านี้เราก็จะได้หน้าตาของเว็บไซต์เปลี่ยนไปตามต้องการ
ตัวอย่าง
ธีมหลัก มีไฟล์ stye.css, functions.php, header.php
ธีมลูก ก็ให้มีไฟล์แบบเดียวกัน คือ style.css, functions.php และ header.php เมื่อเราต้องการที่จะแก้ header.php ในธีมหลัก ให้เราแก้ที่ header.php ที่ธีมลูก
การแก้ functions.php
ต้องทำการแก้ไขด้วยการลบ (เมื่อไม่ต้องการใช้ฟังก์ชั่นใดๅ) และ เพิ่ม
สามารถแก้ไขข้อมูลดังต่อไปนี้
1.ฟีเจอร์ของธีม (Theme features) เช่น กลุ่มฟังก์ชั่น add_theme_support() เช่น
- post-formats
- post-thumbnails
- custom-background
- custom-header
- automatic-feed-links
เราสามารถยกเลิกได้ด้วยการใช้ฟังก์ชั่น remove_theme_support() ตามด้านล่าง
function remove_parent_theme_features() { remove_theme_support( 'post-formats' ); remove_theme_support( 'post-thumbnails' ); remove_theme_support( 'custom-background' ); remove_theme_support( 'custom-header' ); remove_theme_support( 'automatic-feed-links' ); }
2.ประเภทของบทความพิเศษและกลุ่มบทความพิเศษ (Custom Post Types and Taxonomies)
เราสามารถเอาประเภทบทความพิเศษนี้ออกได้ด้วยการนำออก (Remove) โดยใช้ฟังก์ชั่น remove_action()
เพิ่มบทความพิเศษเข้าไปได้ด้วยฟังก์ชั่น add_action()
กันจากตัวอย่างด้านล่างจะเป็นการลงทะเบียนประเภทของบทความพิเศษ (Custom Post Types) ในธีมหลัก (Parent Theme)
// PARENT functions.php add_action( 'after_setup_theme', 'parent_movie_add_post_type' ); function parent_movie_add_post_type() { $parent_args = array( // other arguments... 'rewrite' => array( 'slug' => 'movie' ), 'supports' => array( 'title', 'editor', 'author', 'excerpt' ) ); register_post_type( 'movie', $parent_args ); }
หากเราไม่ต้องการใช้งานประเภทของบทความพิเศษนั้น ตามตัวอย่างด้านล่าง
// CHILD functions.php function remove_parent_theme_features() { // remove Movie Custom Post Type remove_action( 'init', 'parent_movie_add_post_type' ); /* alternatively, we can add our custom post type to overwrite only some aspects of the parent function */ add_action( 'init', 'child_movie_post_type' ); } function child_movie_post_type() { $child_args = array( // other arguments... // change Custom Post slug 'rewrite' => array( 'slug' => 'child-movie' ), // remove excerpts and add post thumbs 'supports' => array( 'title', 'editor', 'author', 'thumbnail' ) ); register_post_type( 'movie', $child_args ); }
นอกจากที่เราจะนำออก (Remove) ประเภทของบทความพิเศษได้ทั้งหมดแล้ว เรายังสามารถเอาฟีเจอร์เฉพาะบางอย่างออกโดยไม่จำเป็นต้องนำประเภทของบทความพิเศษออกทั้งหมดก็ได้ จากตัวอย่างจะเห็นว่าเราจะนำเฉพาะฟีเจอร์สิ่งที่คัดตอนมา (Excerpt) ออก แล้วนำฟีเจอร์รูปภาพขนาดเล็ก (Thumbnail) ใส่เข้าไปแทนได้ โดยการใช้ฟังก์ชั่น remove_post_type_support() และ add_post_type_support() ตามลำดับ
function remove_parent_theme_features() { add_action( 'init', 'wp_tuts_remove_post_feature' ); } function wp_tuts_remove_post_feature() { // remove excerpt remove_post_type_support( 'movie', 'excerpt' ); // add post thumbs add_post_type_support( 'movie', 'thumbnail' ); }
ในส่วนของ Taxonomy ก็เช่นเดียวกัน เราสามารถนำออก (Remove) ได้ด้วยฟังก์ชั่น remove_action() ไปที่ฟังก์ชั่น parent_taxonomy()
function wp_tuts_after_setup_theme() { remove_action( 'init', 'parent_taxonomy' ); }
3. การนำเมนูออกจากธีมหลัก เราสามารถนำออก (Remove) ออกได้ ด้วยฟังก์ชั่นที่ชื่อว่า unregister_nav_menu() โดยให้ทำการใส่รหัสของเมนู (Menu ID) ที่ธีมเราสร้างขึ้นมาเป็นพารามิเตอร์ของฟังก์ชั่นนี้ ยกตัวอย่างเช่น ตามโค๊ดธีมหลักของเรามีเมนูที่ลงทะเบียนไว้ชื่อ Header Menu
// PARENT functions.php add_action( 'after_setup_theme', 'register_my_menu' ); function register_my_menu() { register_nav_menu( 'header-menu', __( 'Header Menu' ) ); }
เมื่อเราไม่ต้องการใช้เมนูนี้ในธีมลูก ให้เราใช้ฟังก์ชั่น unregister_nav_menu() แล้วใส่พารามิเตอร์เป็นรหัสของเมนู
// CHILD functions.php function remove_parent_theme_features() { unregister_nav_menu( 'header-menu' ); }
4. การนำวิดเจ็ต (Widgets) และแถบด้านข้างออก (Sidebar)
ในกรณีที่เป็นวิดเจ็ต เราสามารถนำออก (Remove) ด้วยฟังก์ชั่น unregister_widget() โดยหากเป็นวิดเจ็ตพื้นฐาน (Default Widgets) ที่มาจากระบบเวิร์ดเพรส เราก็สามารถนำออกได้เลยโดยใช้ชื่อของวิดเจ็ตนั้นๆ เป็นพารามิเตอร์ เช่น unregister_widget( ‘WP_Widget_Pages’ ); แต่ถ้าเป็นวิดเจ็ตที่มาจากธีมที่เราใช้งาน ซึ่งจะเป็นการขยายมาจากฟังก์ชั่น WP_Widget ของระบบเวิร์ดเพรสในลักษณะ Class เราห้ามทำการนำออกทั้งก้อนที่เป็น WP_widget แต่ให้เรานำออกในส่วนที่ขยายเท่านั้น
// PARENT theme class ParentWidgetName extends WP_Widget { // widget code }
add_action( 'widgets_init', 'wp_tuts_parent_unregister_widgets', 10 ); function wp_tuts_parent_unregister_widgets() { // remove (some) WordPress default Widgets unregister_widget( 'WP_Widget_Pages' ); unregister_widget( 'WP_Widget_Calendar' ); // remove Parent registered Widget unregister_widget( 'ParentWidgetName' ); // register a custom Widget (if needed) register_widget( 'MyCustomWidget' ); } // don't forget to add the Widget Class class MyCustomWidget extends WP_Widget { // Custom Widget code }
จากโค๊ดด้านบนในกรณีที่เราต้องการเพิ่มวิดเจ็ตเข้าไปใหม่ในธีมลูก ให้ใช้ฟังก์ชั่นที่ชื่อ register_widget() เพื่อทำการลงทะเบียนวิดเจ็ตของเรา และจะต้องสร้างคลาส (Class) ขึ้นมาเพื่อขยายฟังก์ชั่นพื้นฐานของระบบเวิร์ดเพรสที่ชื่อ WP_Widget แล้วทำการเขียนโค๊ดของวิดเจ็ตที่เราต้องการในคลาส (Class) นี้
สำหรับแถบด้านข้าง (Sidebar) ก็จะทำในลักษณะใกล้เคียงกัน โดยจะใช้ฟังก์ชั่น unregister_sidebar() ซึ่งมีพารามิเตอร์เป็นรหัสของแถบด้านข้าง (Sidebar ID) นั้นๆ
add_action( 'widgets_init', 'wp_tuts_parent_unregister_sidebars', 10 ); function wp_tuts_parent_unregister_sidebars() { // remove a sidebar registered by the Parent Theme unregister_sidebar( 'first-footer-widget-area' ); }
ทั้งนี้วิดเจ็ต (Widgets) และแถบด้านข้าง (Sidebar) นี้จะใช้การฮุก (Hook) ตั้งแต่เริ่มต้นวิดเจ็ต (widgets_init) ด้วยฟังก์ชั่น add_action()
5. การนำออก Shortcodes (Remove Shortcodes)
การนำออก Shortcode นั้นสามารถทำได้ด้วยฟังก์ชั่น remove_shortcode() และหากจะเพิ่มเข้าไปให้ใช้ฟังก์ชั่นที่ชื่อ add_shortcode() ตามโค๊ดด้านล่าง
function remove_parent_theme_features() { // remove the parent [gmap] shortcode remove_shortcode( 'gmap' ); // add our [gmap] shortcode add_shortcode( 'gmap', 'child_shortcode_gmap' ); } function child_shortcode_gmap( $atts ) { // create our shortcode that overwrites the parent one }
ในกรณีที่เราไม่ต้องการใช้ขนาดรูปภาพที่ถูกกำหนดมาให้ธีมหลัก เราสามารถแก้ไขได้โดยหาฟังก์ชั่นที่ชื่อ add_image_size() ในธีมหลัก เพื่อดูว่าชื่อของขนาดรูปภาพที่เราไม่ต้องการนั้นมีชื่อว่าอะไร เช่นในที่นี้ให้ชื่อว่า custom_size_parent_1 และ custom_size_parent_2 ให้เราทำการ unset ในขนาดของรูปนั้นๆ ออกตามโค๊ดด้านล่าง
add_filter( 'intermediate_image_sizes_advanced', 'remove_parent_image_sizes' ); function remove_parent_image_sizes( $sizes ) { unset( $sizes['custom_size_parent_1'] ); unset( $sizes['custom_size_parent_2'] ); return $sizes; }
if ( function_exists( 'add_image_size' ) ) { // 400 pixels wide and unlimited height add_image_size( 'custom_size_child_1', 400, 9999 ); // 320 pixels wide and 240 px tall, cropped add_image_size( 'custom_size_child_2', 320, 240, true ); }
เราสามารถนำออก (Remove) ในส่วนของ Metaboxes ที่เราไม่ต้องการได้ด้วยการใช้ฟังก์ชั่น remove_meta_box() ซึ่งจะประกอบไปด้วย 3 พารามิเตอร์หลัก ได้แก่ รหัสของ Metabox (Metabox ID) ส่วนที่ต้องการนำออก และตำแหน่งของ Metabox นั้นๆ ในที่นี้จะเห็นว่า เรานำ Metabox ที่ชื่อ traxckbacksdiv ออก โดยอยู่ในส่วนของบทความ (Post) และอยู่ในตำแหน่งปกติ (Normal) เป็นต้น
add_action( 'admin_menu' , 'wp_tuts_remove_metaboxes', 99 ); function wp_tuts_remove_metaboxes() { // remove default WP Trackback Metabox from Posts editing page remove_meta_box( 'trackbacksdiv', 'post', 'normal' ); // remove a Parent Theme Metabox 'parent_post_foo_metabox' remove_meta_box( 'parent_post_foo_metabox', 'post', 'normal' ); }
8. การนำออกในส่วนของ Javascripts และ CSS Stylesheets
สำหรับส่วนของ Javascripts และ CSS Stylesheets นั้น ในการนำออกนั้นให้เราจะใช้ฟังก์ชั่น wp_deregister_script() และ wp_deregister_style() แล้วให้เราทำการฮุก (Hook) ไปที่ ตำแหน่งที่ Scripts และ Style ที่ระบุไว้ตามลำดับ
// PARENT functions.php add_action( 'wp_print_scripts', 'parent_scripts' ); add_action( 'wp_print_styles', 'parent_styles' ); function parent_scripts() { wp_enqueue_script( 'fancybox-parent-js', get_stylesheet_directory_uri() . '/fancybox/jquery.fancybox.pack.js' ); } function parent_styles() { wp_enqueue_style( 'fancybox-parent-css', get_stylesheet_directory_uri() . '/fancybox/jquery.fancybox.css' ); }
จากโค๊ดด้านล่างจะเห็นว่าเราทำการฮุกไปที่ wp_print_scripts และ wp_print_styles ตามที่เราสร้างไว้ตอนเริ่มต้น
// CHILD functions.php add_action( 'wp_print_scripts', 'child_overwrite_scripts', 100 ); add_action( 'wp_print_styles', 'child_overwrite_styles', 100 ); function child_overwrite_scripts() { wp_deregister_script( 'fancybox-parent-js' ); } function child_overwrite_styles() { wp_deregister_style( 'fancybox-parent-css' ); }
9. การนำออกในส่วนของ Actions และ Filters
ในบางครั้ง ธีมหรือ Woocommerce ที่เราใช้มีการใช้งานประเภท Actions และ Filters เป็นจำนวนมาก เราก็สามารถทำการปรับเปลี่ยนในส่วนของ Actions และ Filters ได้เช่นเดียวกัน โดยให้ใช้ฟังก์ชั่น remove_action ในการนำออก
// Unhook default Thematic functions function unhook_thematic_functions() { // we put the position number of the original function (5) // for priority reasons remove_action( 'thematic_header', 'thematic_blogdescription', 5 ); } add_action( 'init', 'unhook_thematic_functions' );
ยังมีฟังก์ชั่นบางจำพวกที่จะใช้เฉพาะในส่วนของธีมลูก (Child Theme) เท่านั้น เช่น get_stylesheet_directory_uri() ในขณะที่ธีมหลักจะใช้ get_template_directory_uri() แทน ซึ่งฟังก์ชั่นนี้จะเป็นฟังก์ชั่นที่ใช้เรียกตำแหน่งของไฟล์ต่างๆ ครับ ตัวอย่างเช่น
<img src="<?php echo get_stylesheet_directory_uri(); ?>/images/aternus.png" alt="" width="" height="" />
ที่มา http://www.themevilles.com
เพิ่มเติม
/* WordPress ไม่แนะนำให้ใช้โค้ดแบบข้างล่างนี้อีกต่อไป */ @import url("../FatherTheme/style.css");
เพราะ ถ้าสมมุติมี Plugin อยู่หลายตัว หรือใน Theme เรียกใช้ CSS ชุดเดียวกันอยู่หลายๆครั้ง วิธีการแบบข้างบน อาจจะทำให้เกิดการโหลดแบบซ้ำๆ กันเกิดขึ้น ซึ่งแตกต่างจากการใช้ฟังก์ชั่นของ WordPress ช่วยจัดการโหลด CSS เหล่านั้นขึ้นมาให้ ทำให้แทนที่จะต้องโหลดไฟล์ซ้ำๆ กัน ก็โหลดเพียงแค่ครั้งเดียว (อ้างอิง)
Why is this the best solution to adding styles to your WordPress page? This is because of the function wp_enqueue_style, this will handle all of the stylesheets that need to be added to the page and will do it in one place.
วิธีการก็คือ เราจะต้องสร้างไฟล์อีกไฟล์นึงขึ้นมา ชื่อว่า functions.php แล้วก็ใส่โค้ดชุดข้างล่างนี้ลงไป
<?php //.... add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' ); function theme_enqueue_styles() { wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' ); }
เท่านี้ก็เป็นการผลักการโหลดไฟล์ ให้ WordPress เป็นตัวจัดการ
เพิ่มเติม
https://code.tutsplus.com/articles/how-to-modify-the-parent-theme-behavior-within-the-child-theme–wp-31006
https://codex.wordpress.org/Child_Themes