7
Sep

ทำ Short code สำหรับ Visual Composer แบบ Nested

Category: Blog / 227 views

สวัสดีครับผม กลับมาพบกันใหม่กับบทความตอนใหม่ ก่อนหน้านี้ผมเคยเขียนบทความเกี่ยวกับการทำ Shortcode สำหรับ visual composer แบบง่ายๆมาแล้ว และก็รับปากไว้ว่าจะเล่าถึงการเขียนแบบซับซ้อนมากขึ้น ซึ่งวิธีการทำจริงๆก็ไม่ยุ่งยากเท่าไหร่ครับ

สำหรับวิธีการทำครั้งนี้จะเป็นการทำสำหรับข้อมูลที่มีการวนลูปอยู่ภายในครับ เช่น สมมติว่าผมจะทำ shortcode สำหรับทำ Slider ซึ่งแน่นอนว่า มันก็ต้องมี slider อย่างน้อยหนึ่งอันขึ้นไปอยู่ในก้อนเดียวกัน แล้วถ้าจะทำแบบนี้เราจะทำอย่างไร มามะมาดูกันครับ

เช่นเคยครับ อย่างแรก เราต้องเขียน mockup ในรูปแบบ HTML มาให้ได้เสียก่อน อย่างในตัวอย่างนี้ผมจะยกตัวอย่างการทำ Slide ครับ และนี่คือ Demo Mockup ของผม

slide

โดยในภาพด้านบน หนึ่งสไลด์ของผมประกอบไปด้วย

  1. รูปภาพพื้นหลัง
  2. ข้อความที่เป็น Head line (Music Fest#2)
  3. ข้อความ sub text (the rock in your heart will boom!)
  4. ข้อความบนปุ่ม (Buy ticket)
  5. ลิงค์สำหรับปุ่ม

โค้ด 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 {
}
}

 

คำอธิบาย

เราจะแยกข้อมูลออกเป็นสองส่วนครับ คือส่วนของ “โครงสร้างหลัก” และ “เนื้อหาข้างในที่รูปแบบซ้ำกัน”  โดยตัวโครงสร้างหลักนั้น ก็จะเป็นบรรทัดที่ 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

Tags:


Phraisohn Siripool is a Graphic Designer and Website Developer. Contact Buksohn for Your Business Endeavours