[ตอนที่ 2] เวิร์คช้อป CMS อย่างง่าย เก็บข้อมูลเป็นไฟล์
กระบวนการแสดงผลหน้าเว็บของ TCMS จะมีข้อแตกต่างไปจากโปรเจ็คก่อนหน้าเล็กน้อยเท่านั้น เช่น
ในโปรเจ็คนี้ Controller หลักจะไม่ทำการเลือกหน้าเพจมาแสดงผลเอง แต่จะส่งต่อไปจัดการเลือกหน้ามาแสดงผลโดย Index\Main\Controller แทน
อธิบายทีละส่วนเลยครับ
บรรทัดนี้จะเป็นการเรียกไปยัง \Index\Module\Model::get() อีกที
ซึ่ง \Index\Module\Model::get() จะทำหน้าที่ในการตรวจสอบว่า มีไฟล์ $module.php ใน datas/index/ หรือไม่ ถ้ามีก็โหลดไฟล์แล้วส่งค่ากลับมา
กลับไปที่ Index\Main\Controller บรรทัดถัดมา
โค้ดชุดนี้จะตรวจสอบว่ามีหน้าเพจโหลดมาหรือไม่ ถ้าไม่มีจะไปใช้ข้อมูลจาก Index\Pagenotfound\Controller แทน
สุดท้ายเป็นโค้ดส่วนแสดงผล
จะเห็นว่าในโปรเจ็คนี้จะมีการโหลดเนื้อหาแล้วนำข้อมูลไปใส่ลงใน main.html อีกที เพื่อแสดงผล แทนการโหลดไฟล์ HTML ซึ่งเป็นวิธีการของ CMS นั่นเอง
โค้ดของ main.html ก็มีเท่านี้แหละครับ TOPIC แสดงส่วนหัวข้อ ส่วน DETAIL แสดงส่วนเนื้อหา
ข้อดีของการเก็บข้อมูลเนื้อหาเป็นไฟล์ PHP ตามวิธีนี้ คือ ข้อมูลเนื้อหาจะไม่สามารถเข้าถึงได้เลยจากบุคคลภายนอก ถึงแม้จะรู้ URL (ตัวอย่างก่อน เป็นไฟล์ HTML เราสามารถเรียกเฉพาะส่วนที่เป็นเนื้อหาเท่านั้นได้โดยการเรียกไปยังไฟล์โดยตรง)
ส่วนเมนู เราจะทำการโหลดเมนูที่ Index\Menu\Model::get()
โดยที่ method \Index\Menu\Model::get() เมื่อเรียกมาแล้ว ตัว method จะทำหน้าที่ตรวจสอบว่ามีไฟล์ /datas/menus.php หรือไม่ ถ้ามีก็จะทำการโหลดไฟล์ และทำการจัดรูปแบบของตัวแปรเมนูให้เหมาะสม ก่อนที่จะส่งกลับไปสร้างเมนูด้วย method \Kotchasan\Menu::render() เพื่อแสดงผลต่อไป
ถ้าเปิดดูไฟล์ /datas/menus.php จะพบว่ามันมีรูปแบบคล้ายโค้ดเมนูในโปรเจ็คก่อนหน้านั่นเอง (โปรเจ็คนี้ไม่สนับสนุนเมนูย่อย เนื่องจากมันจะต้องมีวิธีจัดการที่ยุ่งยากกว่า)
// เรียกไปยัง Index\Main\Controller เพื่อโหลดหน้าเว็บ
$index = createClass('Index\Main\Controller')->init($request, $module);
ในโปรเจ็คนี้ Controller หลักจะไม่ทำการเลือกหน้าเพจมาแสดงผลเอง แต่จะส่งต่อไปจัดการเลือกหน้ามาแสดงผลโดย Index\Main\Controller แทน
namespace Index\Main;
use \Kotchasan\Http\Request;
use \Kotchasan\Template;
class Controller extends \Kotchasan\Controller
{
public function init(Request $request, $module)
{
// ตรวจสอบว่ามีไฟล์โมดูลที่ต้องการหรือไม่
$index = \Index\Module\Model::get($module);
if (!$index) {
$index = createClass('Index\Pagenotfound\Controller')->init();
}
// เริ่มต้นใช้งาน View ของโมดูล Main
$view = new \Kotchasan\View;
// ใส่เนื้อหาลงใน View ตามที่กำหนดใน Template
$view->setContents(array(
// หัวข้อ
'/{TOPIC}/' => $index['topic'],
// เนื้อหา
'/{DETAIL}/' => $index['detail']
));
// โหลด template หน้า main (main.html)
$template = Template::load('', '', 'main');
// คืนค่าข้อมูลโมดูล
return (object)array(
'module' => $index['module'],
'title' => $index['topic'],
'detail' => $view->renderHTML($template)
);
}
}
อธิบายทีละส่วนเลยครับ
$index = \Index\Module\Model::get($module);
บรรทัดนี้จะเป็นการเรียกไปยัง \Index\Module\Model::get() อีกที
namespace Index\Module;
class Model
{
public static function get($module)
{
$file = ROOT_PATH.DATA_FOLDER.'index/'.$module.'.php';
if (file_exists($file)) {
return include ($file);
}
return false;
}
}
ซึ่ง \Index\Module\Model::get() จะทำหน้าที่ในการตรวจสอบว่า มีไฟล์ $module.php ใน datas/index/ หรือไม่ ถ้ามีก็โหลดไฟล์แล้วส่งค่ากลับมา
กลับไปที่ Index\Main\Controller บรรทัดถัดมา
if (!$index) {
$index = createClass('Index\Pagenotfound\Controller')->init();
}
โค้ดชุดนี้จะตรวจสอบว่ามีหน้าเพจโหลดมาหรือไม่ ถ้าไม่มีจะไปใช้ข้อมูลจาก Index\Pagenotfound\Controller แทน
สุดท้ายเป็นโค้ดส่วนแสดงผล
// เริ่มต้นใช้งาน View ของโมดูล Main
$view = new \Kotchasan\View;
// ใส่เนื้อหาลงใน View ตามที่กำหนดใน Template
$view->setContents(array(
// หัวข้อ
'/{TOPIC}/' => $index['topic'],
// เนื้อหา
'/{DETAIL}/' => $index['detail']
));
// โหลด template หน้า main (main.html)
$template = Template::load('', '', 'main');
// คืนค่าข้อมูลโมดูล
return (object)array(
'module' => $index['module'],
'title' => $index['topic'],
'detail' => $view->renderHTML($template)
);
จะเห็นว่าในโปรเจ็คนี้จะมีการโหลดเนื้อหาแล้วนำข้อมูลไปใส่ลงใน main.html อีกที เพื่อแสดงผล แทนการโหลดไฟล์ HTML ซึ่งเป็นวิธีการของ CMS นั่นเอง
<h2 class="margin-bottom center">{TOPIC}</h2>
{DETAIL}
โค้ดของ main.html ก็มีเท่านี้แหละครับ TOPIC แสดงส่วนหัวข้อ ส่วน DETAIL แสดงส่วนเนื้อหา
ข้อดีของการเก็บข้อมูลเนื้อหาเป็นไฟล์ PHP ตามวิธีนี้ คือ ข้อมูลเนื้อหาจะไม่สามารถเข้าถึงได้เลยจากบุคคลภายนอก ถึงแม้จะรู้ URL (ตัวอย่างก่อน เป็นไฟล์ HTML เราสามารถเรียกเฉพาะส่วนที่เป็นเนื้อหาเท่านั้นได้โดยการเรียกไปยังไฟล์โดยตรง)
ส่วนเมนู เราจะทำการโหลดเมนูที่ Index\Menu\Model::get()
namespace Index\Menu;
class Model
{
public static function get()
{
$result = array();
if (is_file(ROOT_PATH.DATA_FOLDER.'menus.php')) {
// โหลดรายการเมนู และวนลูปรายการเมนู
foreach (include(ROOT_PATH.DATA_FOLDER.'menus.php') as $item) {
// จัดรูปแบบข้อมูลเมนูให้เหมาะสม สำหรับการสร้างเมนู
$result[$item['module']] = array(
'text' => $item['text'],
'target' => $item['target']
);
if (empty($item['url'])) {
$result[$item['module']]['url'] = WEB_URL.'index.php?module='.$item['module'];
} else {
$result[$item['module']]['url'] = $item['url'];
}
}
}
// คืนค่ารายการเมนูที่จัดรูปแบบแล้ว
return $result;
}
}
โดยที่ method \Index\Menu\Model::get() เมื่อเรียกมาแล้ว ตัว method จะทำหน้าที่ตรวจสอบว่ามีไฟล์ /datas/menus.php หรือไม่ ถ้ามีก็จะทำการโหลดไฟล์ และทำการจัดรูปแบบของตัวแปรเมนูให้เหมาะสม ก่อนที่จะส่งกลับไปสร้างเมนูด้วย method \Kotchasan\Menu::render() เพื่อแสดงผลต่อไป
ถ้าเปิดดูไฟล์ /datas/menus.php จะพบว่ามันมีรูปแบบคล้ายโค้ดเมนูในโปรเจ็คก่อนหน้านั่นเอง (โปรเจ็คนี้ไม่สนับสนุนเมนูย่อย เนื่องจากมันจะต้องมีวิธีจัดการที่ยุ่งยากกว่า)