เขียนธีม WordPress ด้วย Sage 9 – ตอนที่ 3 Blade Template Engine | WP63

เขียนธีม WordPress ด้วย Sage 9 – ตอนที่ 3 Blade Template Engine

ในสองตอนที่ผ่านมาเราได้แนะนำเกี่ยวกับ Sage 9 ไปคร่าวๆ แล้ว  ซึ่งรวมไปถึงสร้างโปรเจ็กท์และการใช้จัดการแพ็คเกจต่างๆ ในขั้นต้นด้วย  ปละในตอนที่ 3 นี้เราจะมาพูดถึงหัวใจสำคัญส่วนหนึ่งของ Sage 9 นั่นคือ Blade Template Engine ครับ

Blade Template Engine แต่เดิมนั้นเป็นระบบเท็มเพลตของเฟรมเวิร์ก Laravel ซึ่งตามคอนเส็ปท์ของมันนั้นจะช่วยให้นักพัฒนาสามารถเขียนเท็มเพลตเพิ่มเติมได้โดยไม่จำเป็นต้องเขียนโค้ดซ้ำในส่วนเดิม

ทำไมต้องใช้ Blade?

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

แต่ด้วยคอนเส็ปท์ของ Blade นั้นที่อาศัยการเขียนโครงหลักและขยายออกไปเรื่อยๆ ทำให้เราสามารถเลี่ยงการเขียนโค้ดซ้ำในจุดนี้ลงไปได้  อีกทั้ง Blade ยังทำหน้าที่เป็น Views ในแนวคิด MVC นั่นหมายความว่าเราสามารถย้าย logic โค้ดของเราไปเก็บไว้ใน Controllers ได้ด้วย  ซึ่งจะทำให้ส่วนเทมเพลตของเรานั้นเหลือแต่โค้ดด้าน Presentation จริงๆ  และทำให้โค้ดสะอาดขึ้น

พื้นฐาน 1: การ Echo และการเขียน Comments

จริงๆ แล้วไฟล์เท็มเพลตของ Blade นั้นเป็นเพียงแค่ไฟล์ PHP ธรรมดาที่มีการแทรกคำสั่งเฉพาะของ Blade เข้ามาด้วย  นั่นหมายความว่าเราสามารถเขียนโค้ด HTML ลงไปในเท็มเพลตได้ทันที

ในกรณีที่เราต้องการที่จะ echo ค่าใดๆ ออกมาก็ตาม (เช่นค่าจากตัวแปรต่างๆ) เราสามารถทำได้ด้วยการใช้วงเล็บปีกกาคู่  เช่น {{ ... }} ซึ่งข้อความที่ถูกแสดงออกมาจะถูก escape เอาไว้ให้โดยอัตโนมัติ

<p class="text">{{ $variable }}</p>
<p class="text">{{ __('Some text for l10n', 'textdomain') }}</p>

ทั้งนี้ด้วยความที่ {{ ... }} จะ escape ข้อความอัตโนมัติ  ทำให้เราไม่สามารถแทรก HTML ลงไปได้

หากเราต้องการแสดงผล HTML ด้วย  ให้เราใช้วงเล็บปีกกาตามด้วยอัศเจรีย์สองตัวดังนั้น {!! ... !!}

<p class="text">{!! $variable !!}</p>
<p class="text">{!! __('Hello <strong>World</strong>', 'textdomain') !!}</p>

สังเกตว่าจะมีการใช้ฟังก์ชัน __() ครอบข้อความเอาไว้ด้วย  ซึ่งฟังก์ชันนี้จะเป็นการช่วยให้ข้อความนี้สามารถเอามาแปลในไฟล์ภาษาได้

สำหรับการเขียนคอมเมนต์ในไฟล์ (เช่นคอมเมนต์ระบุ template name) ให้ใช้วงเล็บปีกกาคู่ ตามด้วยเครื่องหมายลบสองตัว {{-- ... --}}

พื้นฐาน 2: การ Extends ไฟล์เท็มเพลต

ตามแนวคิดของ Sage 9 คือเราจะเขียนเท็มเพลตหลักเอาไว้ไฟล์หนึ่งก่อน  จากนั้นไฟล์เท็มเพลตอื่นๆ ก็เขียน extends จากเท็มเพลตตัวนี้ต่อไป  โดย Sage 9 จะมีเท็มเพลตเริ่มต้นเอาไว้ให้อยู่แล้ว  อยู่ที่ ./resources/views/layouts/app.blade.php ให้ลองเปิดไฟล์นี้ขึ้นมา  จะเห็นว่ามันเป็นแค่โครง HTML คร่าวๆ เท่านั้น  โดยจะทำการเรียก header และ footer ของเว็บเอาไว้ให้เรียบร้อยแล้ว  ทั้งนี้ให้ลองสังเกตว่าจะมีโค้ดส่วนหนึ่งคือคำสั่ง @yield('content')

หากเราเปิดไฟล์เท็มเพลตอื่นๆ ขึ้นมาดู  เช่นไฟล์ ./resources/views/index.blade.php เราจะเห็นว่าไฟล์นี้ไม่มีโครง HTML ใดๆ อยู่เลย  แต่จะพบกับคำสั่งว่า @extends('layouts.app') ซึ่งเป็นการบอกว่าไฟล์เท็มเพลตนี้เป็นการ extends ออกมาจากไฟล์ layouts/app.blade.php และเราจะเห็นอีกคำสั่งคือ @section('content') ... @endsection ซึ่งเป็นการบอกว่าโค้ดในบล็อคนี้จะถูกนำไปแสดงในส่วน @yield('content') ของเท็มเพลตหลัก

โดยในขั้นตอนการคอมไพล์เท็มเพลต (ซึ่งจะคอมไพล์อัตโนมัติ) ไฟล์ index.blade.php จะไปดึงเอาโค้ดจาก layouts/app.blade.php ขึ้นมา  แล้วเอาเนื้อหาใน @section('content') ทั้งหมดไปใส่ไว้ใน @yield('content') ของเท็มเพลตหลัก  จากนั้นเท็มเพลตที่คอมไพล์เสร็จแล้วจะทำการแคชเอาไว้เพื่อใช้งานในภายหลังต่อไป

โดยการ extends นี้สามารถทำต่อไปเรื่อยๆ ได้ไม่มีที่สิ้นสุด

ตัวอย่างการใช้งานง่ายๆ คือสมมุติว่าเว็บเรามี post type ที่ชื่อว่า books เพิ่มมาอันหนึ่ง  โดยในหน้า archive ของ post type นี้ (archive-books.blade.php) จะมีหน้าตาเหมือน archive หลักของเว็บ (archive.blade.php) ทุกประการ  แต่จะต่างกันเล็กน้อยที่ archive ของ books นั้นจะมีช่องค้นหาแบบละเอียดเพิ่มมาด้วย

ในกรณีนี้ไฟล์ archive.blade.php ก็จะ extends ออกมาจาก layouts/app.blade.php ตามปกติ  ในขั้นตอนนี้เราจะเขียนโค้ดหน้า archive ของเราไปตามปกติเลย  แต่จะมีจุดที่เราไป @yield ทิ้งเอาไว้  สมมุติเรา @yield('filter') ก็แล้วกัน

ทีนี้ใน archive-books.blade.php ที่โดยปกติเราต้องเขียนโค้ด archive ใหม่ทั้งหมด (ก็อปโค้ดจาก archive หลัก  แล้วเขียนตรงค้นหาเพิ่มเอา) แต่ใน blade เราสามารถ @extends('archive') ออกมา  แล้วเขียนเพิ่มเฉพาะ @section('filter') ได้เลย   ซึ่งในขั้นตอนการคอมไพล์ archive-books.blade.php จะไปดึงโค้ดจาก archive.blade.php มาอัตโนมัติ  แล้วเอาโค้ดในส่วน @section('filter') ไปใส่ไว้ในส่วน @yield('filter') ให้เราเอง

พื้นฐาน 3: Control structure

การใช้ Control structure หรือคำสั่งเงื่อนไข if ... else และการวนลูปต่างๆ เช่น while, for, และ foreach ใน Blade นั้นจะเหมือนกับการใช้คำสั่งเหล่านี้นี้ใน PHP ปกติทั่วไป  แต่เราจะเริ่มคำสั่งด้วย @<control> และปิดด้วย @end<control>  โดยนิพจน์จะใช้เป็นคำสั่ง PHP ปกติ  เช่น

if ... else

@if( $condition )
  .. stuff ..
@elseif( $another_condition )
  .. stuff ..
@else
  .. stuff ..
@endif

while

@while( $condition )
  .. stuff ..
@endwhile

พื้นฐาน 4: การเรียกใช้ Partial Templates

Partial Templates คือการแบ่งไฟล์เท็มเพลตออกเป็นเท็มเพลตย่อยหลายๆ ไฟล์  ซึ่งจะมีประโยชน์เช่นการเอาโค้ดส่วนเดียวกันไปใช้ซ้ำในหลายๆ หน้า (เช่นอาจจะทำแบนเนอร์ Call to Action แยกเอาไว้  แล้วไป include เข้ามาในบางเท็มเพลต)

โดยปกตินั้นเราจะใช้ฟังก์ชัน get_template_part() กัน  แต่ว่าใน Sage 9 นั้นฟังก์ชันนี้กลับพังยังไม่สามารถใช้งานได้  แต่ว่า Blade ก็มีคำสั่ง @include เอาไว้ให้สำหรับเรียกใช้ Partial Templates เช่นกัน  โดยไฟล์ที่เรียกนั้นจะเป็น relative path กับไดเรคทอรี่ ./resources/views และสามารถใช้เครื่องหมาย . แทนการใช้ / ได้ด้วย

ตัวอย่างเช่นเราจะเรียกใช้ไฟล์ ./resources/views/partials/footer.blade.php ก็สามารถเรียกเข้ามาได้ด้วยคำสั่ง @include('partials.footer')

การส่งค่าตัวแปรไปกับ Partial Templates

คำสั่ง @include นั้นยังเปิดให้เราสามารถส่งค่าตัวแปรไปยัง Partial Templates ที่เราเรียกเข้ามาได้ด้วยโดยให้กำหนดอาร์กิวเมนต์ตัวที่สองเป็นอาเรย์  ซึ่ง array key จะถูกแปลเป็นตัวแปรที่มีค่าเดียวกับค่าที่กำหนดไว้  ตัวอย่างเช่น

index.blade.php

@include('partials.footer', [
  'color' => 'green',
  'show_menu' => true
])

partials/footer.blade.php

<div class="footer footer--{{ $color }}">
  @if( $show_menu )
    <ul class="footer__menu">
      ..
    </ul>
  @endif
  <p class="footer__copyright">
    © 2018 Fresh Consulting
  </p>
</div>

เรียกใช้ไฟล์เท็มเพลต Blade นอกไฟล์เท็มเพลต

ในบางกรณีนั้นเราอาจจะต้องการเรียกใช้ไฟล์เท็มเพลตในส่วนอื่นที่อยู่นอกไฟล์เท็มเพลตหลัก  เช่นเราเขียนวิดเจ็ตให้กับธีม  และต้องการเขียนส่วนแสดงผลของวิดเจ็ตนี้ด้วย Blade

Sage 9 จะมีฟังก์ชันสำหรับเรียกใช้ไฟล์เท็มเพลตเอาไว้ด้วย (จริงๆ คำสั่ง @include ก็ทำงานครอบฟังก์ชันนี้อยู่อีกที )  นั่นคือฟังก์ชัน \App\template( $template_path [, $passing_varisables] )

  • $template_path พาธไปยังไฟล์เท็มเพลต  เป็น relative path กับไดเรคทอรี่ ./resources/views
  • $passing_variables อาเรย์ตัวแปรที่ต้องการส่งไปยัง partial template ที่เรียกเข้ามา

กล่าวคือมันใช้เหมือน @include นั่นเอง

พื้นฐาน 5: การแทรกโค้ด PHP

อย่างที่กล่าวไปก่อนหน้านี้คือ Blade นั้นจริงๆ เป็นไฟล์ PHP ธรรมดาที่มีคำสั่งของ Blade เพิ่มเข้ามาด้วย  ดังนั้นการใส่โค้ด PHP ธรรมดาเข้าไปก็สามารถทำได้เช่นกัน  โดยในบางกรณีเราอาจจะต้องการเรียกฟังก์ชัน PHP ตรงๆ (เช่น template tags ของเวิร์ดเพรสเอง)

การแทรกโค้ด PHP นั้นสามารถทำได้ทั้งการเปิดแท็ก <?php ... ?> แล้วเขียนโค้ดลงไปตรงๆ  หรือใช้คำสั่ง @php ก็ได้  ซึ่งคำสั่ง @php นี้รองรับทั้งการใส่โค้ดบรรทัดเดียวและโค้ดหลายบรรทัด

  • โค้ดบรรทัดเดียวใช้ @php( function_name() )
  • โค้ดหลายบรรทัดใช้ @php ... code @endphp

พิเศษสำหรับคนใช้ VSCode

VSCode หรือ Visual Studio Code เป็น Text Editor ของไมโครซอฟท์ที่เปิดให้ใช้กันฟรีๆ แบบ Open source และด้วยการที่มันมีการพัฒนาแก้บั๊กและเพิ่มฟีเจอร์ใหม่ๆ อย่างสม่ำเสมอ  ทำให้มันได้รับความนิยมขึ้นมาอย่างรวดเร็ว

ทั้งนี้ในค่าเริ่มต้นของ VSCode นั้น  มันจะไม่รองรับการทำ Syntax Highlight ให้กับคำสั่งของ Blade ทำให้หากเราเปิดไฟล์ .blade.php ใน VSCode แล้วจะเป็นโค้ดขาวๆ ดังนี้

แต่ถ้าสังเกตย้อนขึ้นไปจะพบว่าภาพโค้ดตัวอย่างทั้งหมดนั้นมีการทำ Syntax highlight ทั้งหมดเลย

ใช่แล้ว เราสามารถทำให้ VSCode สามารถไฮไลท์คำสั่ง Blade ได้ผ่านส่วนเสริมที่ชื่อว่า laravel-blade

หลังจากติดตั้งและเปิดใช้งานแล้วจะพบว่าตอนนี้ VSCode สามารถไฮไลท์คำสั่ง Blade ได้ถูกต้องแล้ว  แต่เราจะพบกับอีกปัญหาหนึ่งคือ Emmet ไม่สามารถใช้งานได้อีกต่อไป  ซึ่งสาเหตุนั้นมาจากที่ส่วนเสริมตัวนี้ไปกำหนดไฟล์ .blade.php ให้เป็นประเภทไฟล์ใหม่ซึ่ง Emmet ไม่รู้จัก  ทำให้มันปิดการทำงานไปโดยปริยาย

แต่โชคดีว่าเราสามารถไปตั้งค่า Emmet ให้มัน override file type เพื่อสั่งให้ Emmet มองไฟล์ .blade.php เป็นไฟล์ HTML ได้  โดยให้เราไปที่เมนูตั้งค่าของ VSCode

  • Mac: Code > Preferences > Settings
  • Windows: Files > Preferences > Settings

จากนั้นให้เพิ่มการตั้งค่า emmet.includeLanguages เข้าไป (สามารถพิมพ์ค้นหาในพาเนลซ้ายมือได้  เมื่อเจอแล้วให้เอากดไอคอนดินสอหน้าบรรทัดแล้วเลือก Copy to Settings)  จากนั้นให้เพิ่มค่า "blade": "html" เข้าไป

"emmet.includeLanguages": {
  "blade": "html"
},

ให้เซฟการตั้งค่าให้เรียบร้อย  ก็จะพบว่า Emmet กลับมาใช้งานบนไฟล์ Blade ได้อีกครั้ง

ตอนต่อไป

Sage 9 นั้นเป็นธีมที่เอาแนวคิด MVC เข้ามาใช้เพื่อจัดการโค้ดให้เป็นระเบียบยิ่งขึ้น  โดยในส่วนของ Views จะรับหน้าที่เก็บโค้ดส่วน Presentation เท่านั้น  ในขณะที่ Logic ประมวลผลต่างๆ จะถูกโยนไปอยู่ใน Controllers แทน

ในตอนต่อไปเราจะมาพูดถึงการใช้งาน Controllers ใน Sage 9 กัน

บทความตอนอื่นๆ

  1. เขียนธีม WordPress บนเทคโนโลยีสมัยใหม่ด้วย Sage 9 – ตอนที่ 1 แนะนำ Sage 9
  2. เขียนธีม WordPress ด้วย Sage 9 – ตอนที่ 2 ระบบจัดการแพ็คเกจ
  3. เขียนธีม WordPress ด้วย Sage 9 – ตอนที่ 4 ควบคุมข้อมูลด้วย Controller

Posted

in

by

Tags:

Comments

3 responses to “เขียนธีม WordPress ด้วย Sage 9 – ตอนที่ 3 Blade Template Engine”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.