Kotchasan Framework Documentation

Kotchasan Framework Documentation

Menu Class - ระบบเมนู

TH 03 Feb 2026 16:36

Menu Class - ระบบเมนู

คลาส Menu เป็นคลาสสำหรับสร้าง HTML menu จาก array รองรับ nested submenus

Namespace

Kotchasan\Menu

ภาพรวม

คลาส Menu ให้บริการ:

  • สร้าง HTML menu จาก array
  • รองรับ nested submenus (หลายชั้น)
  • แสดง selected state
  • รองรับ target attribute
  • Clean HTML output

Public Methods (2 methods)

render()

สร้าง HTML menu จาก array

public static function render(array $items, string $select): string

พารามิเตอร์:

  • $items - Menu items array
  • $select - ชื่อของ menu ที่เลือก

คืนค่า: HTML string

โครงสร้าง Array:

[
    'menu-name' => [
        'text' => 'Menu Text',      // ข้อความแสดง
        'url' => '/path',           // URL (optional)
        'target' => '_blank',       // Target (optional)
        'submenus' => [...]         // Submenu (optional)
    ]
]

ตัวอย่าง:

use Kotchasan\Menu;

$items = [
    'home' => [
        'text' => 'หน้าแรก',
        'url' => '/'
    ],
    'about' => [
        'text' => 'เกี่ยวกับ',
        'url' => '/about'
    ],
    'products' => [
        'text' => 'สินค้า',
        'submenus' => [
            'electronics' => [
                'text' => 'อิเล็กทรอนิกส์',
                'url' => '/products/electronics'
            ],
            'books' => [
                'text' => 'หนังสือ',
                'url' => '/products/books'
            ]
        ]
    ]
];

$html = Menu::render($items, 'home');
echo $html;

getItem()

สร้าง HTML ของ menu item เดียว (protected - ใช้ภายใน)

protected static function getItem(
    string|int $name,
    array $item,
    bool $arrow,
    string $select
): string

หมายเหตุ: Method นี้เป็น protected ใช้โดย render() เท่านั้น

ตัวอย่างการใช้งานแบบสมบูรณ์

1. Simple Menu

use Kotchasan\Menu;

$menu = [
    'dashboard' => [
        'text' => 'Dashboard',
        'url' => '/dashboard'
    ],
    'users' => [
        'text' => 'Users',
        'url' => '/users'
    ],
    'settings' => [
        'text' => 'Settings',
        'url' => '/settings'
    ]
];

echo '<ul>';
echo Menu::render($menu, 'dashboard'); // 'dashboard' is selected
echo '</ul>';

HTML Output:

<ul>
<li class="dashboard select"><a href="/dashboard" title="Dashboard"><span>Dashboard</span></a></li>
<li class="users"><a href="/users" title="Users"><span>Users</span></a></li>
<li class="settings"><a href="/settings" title="Settings"><span>Settings</span></a></li>
</ul>

2. Multi-Level Menu

use Kotchasan\Menu;

$menu = [
    'home' => [
        'text' => 'Home',
        'url' => '/'
    ],
    'shop' => [
        'text' => 'Shop',
        'submenus' => [
            'electronics' => [
                'text' => 'Electronics',
                'submenus' => [
                    'phones' => [
                        'text' => 'Phones',
                        'url' => '/shop/electronics/phones'
                    ],
                    'laptops' => [
                        'text' => 'Laptops',
                        'url' => '/shop/electronics/laptops'
                    ]
                ]
            ],
            'clothing' => [
                'text' => 'Clothing',
                'url' => '/shop/clothing'
            ]
        ]
    ],
    'contact' => [
        'text' => 'Contact',
        'url' => '/contact'
    ]
];

echo '<ul class="menu">';
echo Menu::render($menu, 'phones');
echo '</ul>';

3. Menu with Target Attribute

use Kotchasan\Menu;

$menu = [
    'internal' => [
        'text' => 'Internal Link',
        'url' => '/page'
    ],
    'external' => [
        'text' => 'External Link',
        'url' => 'https://example.com',
        'target' => '_blank'
    ],
    'docs' => [
        'text' => 'Documentation',
        'url' => 'https://docs.example.com',
        'target' => '_blank'
    ]
];

echo '<ul>';
echo Menu::render($menu, '');
echo '</ul>';

4. Dynamic Menu from Database

use Kotchasan\Menu;
use Kotchasan\Model;

class MenuRenderer
{
    public static function buildMenu($currentPage)
    {
        // ดึงข้อมูลเมนูจากฐานข้อมูล
        $menuItems = Model::create()
            ->from('menus')
            ->where(['status', 1])
            ->order('sort_order')
            ->all();

        // แปลงเป็น array สำหรับ Menu::render()
        $menu = [];
        $submenuMap = [];

        foreach ($menuItems as $item) {
            $menuData = [
                'text' => $item->title,
                'url' => $item->url
            ];

            if ($item->target) {
                $menuData['target'] = $item->target;
            }

            if ($item->parent_id == 0) {
                $menu[$item->alias] = $menuData;
                $submenuMap[$item->id] = &$menu[$item->alias];
            } else {
                if (!isset($submenuMap[$item->parent_id]['submenus'])) {
                    $submenuMap[$item->parent_id]['submenus'] = [];
                }
                $submenuMap[$item->parent_id]['submenus'][$item->alias] = $menuData;
            }
        }

        return Menu::render($menu, $currentPage);
    }
}

// ใช้งาน
echo '<nav>';
echo '<ul class="main-menu">';
echo MenuRenderer::buildMenu('products');
echo '</ul>';
echo '</nav>';

5. Admin Sidebar Menu

use Kotchasan\Menu;
use Kotchasan\Login;

class AdminMenu
{
    public static function render($current)
    {
        $login = Login::isMember();

        $menu = [
            'dashboard' => [
                'text' => 'Dashboard',
                'url' => '/admin/dashboard'
            ]
        ];

        // เฉพาะ admin
        if (Login::isAdmin($login)) {
            $menu['users'] = [
                'text' => 'Users',
                'submenus' => [
                    'list' => [
                        'text' => 'All Users',
                        'url' => '/admin/users'
                    ],
                    'add' => [
                        'text' => 'Add New',
                        'url' => '/admin/users/add'
                    ]
                ]
            ];

            $menu['settings'] = [
                'text' => 'Settings',
                'submenus' => [
                    'general' => [
                        'text' => 'General',
                        'url' => '/admin/settings'
                    ],
                    'security' => [
                        'text' => 'Security',
                        'url' => '/admin/settings/security'
                    ]
                ]
            ];
        }

        $menu['profile'] = [
            'text' => 'My Profile',
            'url' => '/admin/profile'
        ];

        return Menu::render($menu, $current);
    }
}

// ใช้งาน
echo '<aside class="sidebar">';
echo '<ul class="admin-menu">';
echo AdminMenu::render('dashboard');
echo '</ul>';
echo '</aside>';

6. Breadcrumb Menu

use Kotchasan\Menu;

class Breadcrumb
{
    public static function render($path)
    {
        $parts = explode('/', trim($path, '/'));
        $menu = [];
        $url = '';

        $menu['home'] = [
            'text' => 'Home',
            'url' => '/'
        ];

        foreach ($parts as $part) {
            if (!empty($part)) {
                $url .= '/' . $part;
                $menu[$part] = [
                    'text' => ucfirst($part),
                    'url' => $url
                ];
            }
        }

        // Last item is current (no link)
        $last = array_key_last($menu);
        if ($last && $last !== 'home') {
            unset($menu[$last]['url']);
        }

        return Menu::render($menu, $last);
    }
}

// ใช้งาน
echo '<nav class="breadcrumb">';
echo '<ul>';
echo Breadcrumb::render('/products/electronics/phones');
echo '</ul>';
echo '</nav>';

7. Conditional Menu Items

use Kotchasan\Menu;
use Kotchasan\Login;

$login = Login::isMember();

$menu = [];

// สำหรับทุกคน
$menu['home'] = [
    'text' => 'Home',
    'url' => '/'
];

// เฉพาะ logged in
if ($login) {
    $menu['dashboard'] = [
        'text' => 'Dashboard',
        'url' => '/dashboard'
    ];

    // เฉพาะ admin
    if (Login::isAdmin($login)) {
        $menu['admin'] = [
            'text' => 'Admin',
            'submenus' => [
                'users' => [
                    'text' => 'Manage Users',
                    'url' => '/admin/users'
                ],
                'content' => [
                    'text' => 'Content',
                    'url' => '/admin/content'
                ]
            ]
        ];
    }

    $menu['logout'] = [
        'text' => 'Logout',
        'url' => '/logout'
    ];
} else {
    $menu['login'] = [
        'text' => 'Login',
        'url' => '/login'
    ];
}

echo '<ul class="nav">';
echo Menu::render($menu, 'home');
echo '</ul>';

HTML Output Format

<li class="menu-name"><a href="/url" title="Text"><span>Text</span></a></li>
<li class="menu-name select"><a href="/url" title="Text"><span>Text</span></a></li>
<li class="menu-name"><span class=menu-arrow title="Text"><span>Text</span></span><ul>
  <!-- submenu items -->
</ul>
<li class="menu-name"><span title="Text"><span>Text</span></span>

Best Practices

1. Clean Array Structure

// ✅ ดี - โครงสร้างชัดเจน
$menu = [
    'products' => [
        'text' => 'Products',
        'submenus' => [
            'new' => ['text' => 'New', 'url' => '/products/new'],
            'sale' => ['text' => 'Sale', 'url' => '/products/sale']
        ]
    ]
];

// ❌ ไม่ดี - ไม่มี text
$menu = [
    'products' => [
        'url' => '/products'  // Missing 'text'
    ]
];

2. Selected State

// ✅ ดี - ส่ง current page
$current = 'dashboard';
echo Menu::render($menu, $current);

// ✅ ดี - ใช้ empty string ถ้าไม่มี selected
echo Menu::render($menu, '');
// ✅ ดี - ระบุ target สำหรับ external links
$menu = [
    'docs' => [
        'text' => 'Documentation',
        'url' => 'https://docs.example.com',
        'target' => '_blank'
    ]
];

สรุป

คลาส Menu เป็นเครื่องมือง่ายๆ สำหรับ:

  • ✅ สร้าง HTML menu จาก array
  • ✅ รองรับ nested submenus
  • ✅ แสดง selected state
  • 📝 Clean, semantic HTML
  • 🎨 ใช้ CSS เพื่อ styling

เหมาะสำหรับ:

  • Navigation menus
  • Admin sidebars
  • Breadcrumbs
  • Dropdown menus
  • Multi-level menus

ไฟล์ขนาด: 79 บรรทัด
Public Methods: 2 methods (1 public, 1 protected)
Pattern: Static utility class