สวัสดีครับผม กลับมาพบกันใหม่กับบทความตอนใหม่ ก่อนหน้านี้ผมเคยเขียนบทความเกี่ยวกับการทำ Shortcode สำหรับ visual composer แบบง่ายๆมาแล้ว และก็รับปากไว้ว่าจะเล่าถึงการเขียนแบบซับซ้อนมากขึ้น ซึ่งวิธีการทำจริงๆก็ไม่ยุ่งยากเท่าไหร่ครับ
สำหรับวิธีการทำครั้งนี้จะเป็นการทำสำหรับข้อมูลที่มีการวนลูปอยู่ภายในครับ เช่น สมมติว่าผมจะทำ shortcode สำหรับทำ Slider ซึ่งแน่นอนว่า มันก็ต้องมี slider อย่างน้อยหนึ่งอันขึ้นไปอยู่ในก้อนเดียวกัน แล้วถ้าจะทำแบบนี้เราจะทำอย่างไร มามะมาดูกันครับ
เช่นเคยครับ อย่างแรก เราต้องเขียน mockup ในรูปแบบ HTML มาให้ได้เสียก่อน อย่างในตัวอย่างนี้ผมจะยกตัวอย่างการทำ Slide ครับ และนี่คือ Demo Mockup ของผม
โดยในภาพด้านบน หนึ่งสไลด์ของผมประกอบไปด้วย
- รูปภาพพื้นหลัง
- ข้อความที่เป็น Head line (Music Fest#2)
- ข้อความ sub text (the rock in your heart will boom!)
- ข้อความบนปุ่ม (Buy ticket)
- ลิงค์สำหรับปุ่ม
โค้ด HTML ก็เขียนประมาณนี้ครับ
<section class="hero-slider"> <ul class="slides"> <!-- วน Loop Slider ตรงนี้ --> <li class="overlay"> <div class="background-image-holder parallax-background"> <img class="background-image" alt="Background Image" src="images/music.jpg"> </div> <div class="container align-vertical"> <div class="row"> <div class="col-md-6 col-sm-9"> <h1 class="text-white">Music Fest#2</h1> <h2 class="sub-text">the rock in your heart will boom!</h2> <a href="#" class="btn btn-primary btn-filled">BUY TICKET</a> </div> </div> </div> </li> <!-- สิ้นสุด Slider หนึ่งอัน --> </ul> </section>
จากโค้ดด้านบนจะเห็นนะครับว่า เราจะมีการใช้งานตรงที่จะวนลูปคือแท็ก <li>…</li> ครับผม
มาดูโค้ดแบบเต็มกันก่อนนะครับ เขียนลงใน functions.php
/** Slider **/
// Shortcode Slider
if(!function_exists('box_slider')){
function box_slider( $atts, $content = null ) {
return '
<section class="hero-slider">
<ul class="slides">
'.do_shortcode($content).'
</ul>
</section>';
}
add_shortcode('box_slider', 'box_slider');
}
if(!function_exists('single_box_slider')) {
function single_box_slider( $atts, $content = null) {
extract(shortcode_atts(array(
'img' => '',
'headline' => '',
'subtext' => '',
'buttonText' => '',
'link' => '',
), $atts));
$content = wpb_js_remove_wpautop($content, true);
$image = wp_get_attachment_image_src( $img, 'full');
$image_src = $image['0'];
$output ='<li class="overlay">
<div class="background-image-holder parallax-background">
<img class="background-image" alt="Background Image" src="'.$image_src.'">
</div>
<div class="container align-vertical">
<div class="row">
<div class="col-md-6 col-sm-9">
<h1 class="text-white">'.$wording.'</h1>
<h2 class="sub-text">'.$subtext.'</h2>
<a href="'.$link.'" class="btn btn-primary btn-filled">'.$buttonText.'</a>
</div>
</div>
</div>
</li>';
return $output;
}
add_shortcode('single_box_slider', 'single_box_slider');
}
// Mapping
vc_map( array(
"name" => __("Box Slider", "Learn"),
"base" => "box_slider",
"as_parent" => array('only' => 'single_box_slider'),
"content_element" => true,
"show_settings_on_create" => false,
"is_container" => true,
"js_view" => 'VcColumnView',
"category" =>array('Learn', 'Content')
) );
vc_map( array(
"name" => __("Single Slider Content", "Learn"),
"base" => "single_box_slider",
"content_element" => true,
"as_child" => array('only' => 'box_slider'),
"show_settings_on_create" => true,
"params" => array(
array(
'type' => 'attach_image',
'heading' => __( 'Add Image', 'Learn' ),
'param_name' => 'img',
),
array(
"type" => "textfield",
"holder" => "div",
"class" => "",
"heading" => __( "ข้อความบน Slide", "my-text-domain" ),
"param_name" => "headline",
"value" => __( "ใส่ข้อความตรงนี้", "my-text-domain" ),
"description" => __( "ช่องสำหรับพิมพ์ข้อความที่อยู่บน slider", "my-text-domain" )
),
array(
"type" => "textfield",
"holder" => "div",
"class" => "",
"heading" => __( "ข้อความ Subtext บน Slide", "my-text-domain" ),
"param_name" => "subtext",
"value" => __( "ใส่ข้อความตรงนี้", "my-text-domain" ),
"description" => __( "ช่องสำหรับพิมพ์ข้อความที่อยู่บน slider", "my-text-domain" )
),
array(
"type" => "textfield",
"holder" => "div",
"class" => "",
"heading" => __( "ข้อความบนปุ่ม", "my-text-domain" ),
"param_name" => "buttonText",
"value" => __( "ใส่ข้อความตรงนี้", "my-text-domain" ),
"description" => __( "ช่องสำหรับพิมพ์ข้อความที่อยู่บนปุ่ม", "my-text-domain" )
),
array(
"type" => "textfield",
"holder" => "div",
"class" => "",
"heading" => __( "URL", "my-text-domain" ),
"param_name" => "link",
"value" => __( "ใส่ลิงค์สำหรับ ปุ่มบน Slider", "my-text-domain" ),
"description" => __( "ช่องสำหรับใส่ลิงค์ของ slider", "my-text-domain" )
),
),
) );
if ( class_exists( 'WPBakeryShortCodesContainer' ) ) {
class WPBakeryShortCode_Box_Slider extends WPBakeryShortCodesContainer {
}
}
if ( class_exists( 'WPBakeryShortCode' ) ) {
class WPBakeryShortCode_Single_Box_Slider extends WPBakeryShortCode {
}
}
[thetext]คำอธิบาย[/thetext]
เราจะแยกข้อมูลออกเป็นสองส่วนครับ คือส่วนของ “โครงสร้างหลัก” และ “เนื้อหาข้างในที่รูปแบบซ้ำกัน” โดยตัวโครงสร้างหลักนั้น ก็จะเป็นบรรทัดที่ 8 ถึงบรรทัดที่ 12 ครับ สังเกตดูนะครับว่า เราจะเขียนถึงแค่ <ul> เท่านั้น และข้างในโครงสร้างหลัก ก็ใช้คำสั่ง do_shortcode($content) เพื่อเรียกเนื้อหาที่เป็นรูปแบบซ้ำๆมาแสดงผลตรงบรรทัดที่ 10
extract(shortcode_atts(array( 'img' => '', 'headline' => '', 'subtext' => '', 'buttonText' => '', 'link' => '',
โค้ดด้านบนเป็นการ extract ค่าที่ได้มาเก็บไว้ในตัวแปรเพื่อเตรียมไปใช้งานต่อครับ (บรรทัดที่ 21 ถึงบรรทัดที่ 28 ในโค้ดชุดเต็ม)
$content = wpb_js_remove_wpautop($content, true); $image = wp_get_attachment_image_src( $img, 'full'); $image_src = $image['0']; $output ='<li class="overlay"> <div class="background-image-holder parallax-background"> <img class="background-image" alt="Background Image" src="'.$image_src.'"> </div> <div class="container align-vertical"> <div class="row"> <div class="col-md-6 col-sm-9"> <h1 class="text-white">'.$wording.'</h1> <h2 class="sub-text">'.$subtext.'</h2> <a href="'.$link.'" class="btn btn-primary btn-filled">'.$buttonText.'</a> </div> </div> </div> </li>'; return $output;
โค้ดด้านบนเป็นการเอาตัวแปรที่ได้มาใช้ร่วมกับโค้ด HTML ของเราครับ ก็แปะๆไป ใช้งานง่ายมากครับ เป็นการเชื่อมสตริงแบบปกติ
// Mapping
vc_map( array(
"name" => __("Box Slider", "Learn"),
"base" => "box_slider",
"as_parent" => array('only' => 'single_box_slider'),
"content_element" => true,
"show_settings_on_create" => false,
"is_container" => true,
"js_view" => 'VcColumnView',
"category" =>array('Learn', 'Content')
) );
vc_map( array(
"name" => __("Single Slider Content", "Learn"),
"base" => "single_box_slider",
"content_element" => true,
"as_child" => array('only' => 'box_slider'),
"show_settings_on_create" => true,
"params" => array(
array(
'type' => 'attach_image',
'heading' => __( 'Add Image', 'Learn' ),
'param_name' => 'img',
),
array(
"type" => "textfield",
"holder" => "div",
"class" => "",
"heading" => __( "ข้อความบน Slide", "my-text-domain" ),
"param_name" => "headline",
"value" => __( "ใส่ข้อความตรงนี้", "my-text-domain" ),
"description" => __( "ช่องสำหรับพิมพ์ข้อความที่อยู่บน slider", "my-text-domain" )
),
array(
"type" => "textfield",
"holder" => "div",
"class" => "",
"heading" => __( "ข้อความ Subtext บน Slide", "my-text-domain" ),
"param_name" => "subtext",
"value" => __( "ใส่ข้อความตรงนี้", "my-text-domain" ),
"description" => __( "ช่องสำหรับพิมพ์ข้อความที่อยู่บน slider", "my-text-domain" )
),
array(
"type" => "textfield",
"holder" => "div",
"class" => "",
"heading" => __( "ข้อความบนปุ่ม", "my-text-domain" ),
"param_name" => "buttonText",
"value" => __( "ใส่ข้อความตรงนี้", "my-text-domain" ),
"description" => __( "ช่องสำหรับพิมพ์ข้อความที่อยู่บนปุ่ม", "my-text-domain" )
),
array(
"type" => "textfield",
"holder" => "div",
"class" => "",
"heading" => __( "URL", "my-text-domain" ),
"param_name" => "link",
"value" => __( "ใส่ลิงค์สำหรับ ปุ่มบน Slider", "my-text-domain" ),
"description" => __( "ช่องสำหรับใส่ลิงค์ของ slider", "my-text-domain" )
),
โค้ดชุดนี้เป็นการสร้างฟิลด์สำหรับรับข้อมูล ของ “โครงสร้างภายในที่มีการใช้งานซ้ำๆกัน” ครับ โดยวิธีการเขียนก็เหมือนกับบทความด้านบนที่ผมแปะให้ครับ พวกคำอธิบายโค้ดชุดนี้สามารถอ่านได้จากบทความก่อนหน้านี้ได้เลย โดยบรรทัดที่สำคัญคือบรรทัดที่เขียนว่า
"base" => "box_slider",
เพราะเป็นการบอกให้รู้ว่าตัวฟิลด์พวกนี้จะใช้งานเป็นโครงสร้างภายในของโครงสร้างหลักตัวไหน อย่างของผมโครงสร้างหลักมีชื่อว่า box_slider นั่นเอง
สำหรับชื่อฟังก์ชั่นต่างๆนั้นก็ให้เราแก้ไขเป็นของเราเองได้เลยนะครับ ลองดูโค้ดตัวอย่างของผมแล้วนำไปปรับแต่งต่อดูครับ ไม่ยากๆ ลองทำแบบง่ายๆดูก่อนแล้วจะเข้าใจมากยิ่งขึ้นครับผม
และนี่แหละครับคือวิธีการเขียน Shortcode สำหรับ visual composer แบบ Nested หากอยากรู้เพิ่มเติมลองอ่านที่บทความของ Visual Composer ได้นะครับ ที่ลิงค์นี้ครับ แล้วเจอกันใหม่บทความหน้าครับ
https://wpbakery.atlassian.net/wiki/pages/viewpage.action?pageId=524362





