Widget Element (Builder)
1. Tổng Quan Kiến Trúc
1.1 Hệ thống phân cấp Class
1.2 Ba loại Element trong Builder
| Loại | Vị trí trong widget.json | Sử dụng |
|---|---|---|
| Header Elements | elements.header | Chỉ dùng trong Header Builder |
| Footer Elements | elements.footer | Chỉ dùng trong Footer Builder |
| General Elements | elements.general | Dùng được trong cả Header, Footer và Home/Page Builder |
1.3 Các Category mặc định
| Key | Tên hiển thị | Mô tả |
|---|---|---|
layout | Bố cục | Container, Inner Section |
basic | Cơ bản | Heading, Image, Text, Video, Button |
general | Chung | Elements chung |
| header | Header | Logo, Cart, Search |
heading | Tiêu đề | Các kiểu heading |
| footer | Footer | Footer blocks |
ecommerce | Thương mại điện tử | Products, Cart |
2. Cấu Trúc Thư Mục
2.1 Cấu trúc chuẩn cho một Element
views/theme-store/widget/elements/{element-name}/
├── {element-name}.widget.php # Class chính (extends Element)
├── views/
│ └── view.blade.php # Template hiển thị
└── assets/ # (Tùy chọn) CSS/LESS/JS riêng
├── {element-name}.css
├── {element-name}.less
└── {element-name}.js
2.2 Ví dụ thực tế
widget/elements/video/
├── video.widget.php # VideoWidgetElement class
├── views/
│ └── view.blade.php
└── assets/
├── video-widget.less
├── video-widget.css
└── video-widget.css.map
3. Tạo Element Cơ Bản (Step-by-step)
Bước 1: Tạo file Widget Class
Tạo file views/theme-store/widget/elements/my-element/my-element.widget.php:
<?php
use SkillDo\Cms\Element\Element;
use SkillDo\Cms\Support\Theme;
class MyElementWidget extends Element
{
function __construct()
{
// Tham số 1: Key duy nhất (tên class)
// Tham số 2: Tên hiển thị trong admin
parent::__construct('MyElementWidget', 'Tên Element');
}
/**
* Icon hiển thị trong danh sách elements
* Trả về key trong danh sách icons đã đăng ký (ElementManager::getIcon)
* Các key có sẵn: heading, image, text-editor, video, button,
* icon, icon-box, divider, counter, tabs,
* accordion, form, nav-menu, google-maps, ...
*/
public function icon(): string
{
return 'icon-box';
}
/**
* Category để nhóm element trong sidebar admin
* Các category có sẵn: layout, basic, general, header,
* heading, footer, ecommerce
*/
public function category(): string
{
return 'basic';
}
/**
* Khai báo form cấu hình cho element trong admin
*/
public function form(): void
{
// Thêm fields vào tab "Nội dung" (generate)
$this->tabs('generate')->adds(function (\SkillDo\Cms\Form\Form $form)
{
$form->text('title', ['label' => 'Tiêu đề']);
$form->wysiwyg('content', ['label' => 'Nội dung']);
});
// QUAN TRỌNG: Luôn gọi parent::form() ở cuối
parent::form();
}
/**
* Render HTML đầu ra cho element
*/
public function widget(): void
{
Theme::view($this->getDir().'/views/view', [
'id' => $this->id,
'options' => $this->options,
]);
}
/**
* (Tùy chọn) Thiết lập giá trị mặc định
*/
public function default(): void
{
$this->options->title = $this->options->title ?? 'Tiêu đề mặc định';
$this->options->content = $this->options->content ?? 'Nội dung mặc định...';
}
}
Bước 2: Tạo View Template
Tạo file views/theme-store/widget/elements/my-element/views/view.blade.php:
<div class="my-element-widget">
@if(!empty($options->title))
<h3 class="title">{!! $options->title !!}</h3>
@endif
@if(!empty($options->content))
<div class="content">{!! $options->content !!}</div>
@endif
</div>
Bước 3: Đăng ký Element trong widget.json
Mở file views/theme-store/widget/widget.json và thêm vào mục elements:
{
"elements": {
"general": {
"MyElementWidget": {
"path": "widget/elements/my-element/my-element.widget.php"
}
}
}
}
[!IMPORTANT] Key trong JSON (
"MyElementWidget") phải trùng khớp chính xác với tên class PHP. Hệ thống sử dụng key này để tìm và khởi tạo class.
[!NOTE]
- Đăng ký trong
elements.header→ chỉ dùng trong Header Builder- Đăng ký trong
elements.footer→ chỉ dùng trong Footer Builder- Đăng ký trong
elements.general→ dùng được ở mọi builder (header, footer, home, page)
4. Hệ Thống Form — Khai Báo Fields
4.1 Cấu trúc Tab
Mỗi Element có 3 tab mặc định:
| Tab | Key | Mục đích |
|---|---|---|
| ✏️ Nội dung | generate | Dữ liệu chính (text, image, select...) |
| 🎨 Kiểu dáng | style | Tùy chỉnh giao diện (màu s ắc, font, border...) |
| ⚙️ Nâng cao | advanced | Spacing, Motion Effects (tự động thêm bởi Element) |
4.2 Thêm fields vào tab
public function form(): void
{
// Tab "Nội dung"
$this->tabs('generate')->adds(function (\SkillDo\Cms\Form\Form $form)
{
// Các field input sẽ được thêm ở đây
});
// Tab "Kiểu dáng"
$this->tabs('style')->adds(function (\SkillDo\Cms\Form\Form $form)
{
// Các field style sẽ được thêm ở đây
});
parent::form();
}
4.3 Các loại field phổ biến
Text & Content
// Text input đơn giản
$form->text('field_name', ['label' => 'Label hiển thị']);
// Text hỗ trợ đa ngôn ngữ
$form->text('field_name', ['label' => 'Label', 'language' => true]);
// WYSIWYG Editor (TinyMCE)
$form->wysiwyg('content', ['label' => 'Nội dung']);
// Textarea
$form->textarea('description', ['label' => 'Mô tả']);
// Number input
$form->number('count', ['value' => 5, 'label' => 'Số lượng', 'start' => 6]);
Media
// Image picker
$form->image('image', ['label' => 'Chọn ảnh']);
// File upload
$form->file('document', ['label' => 'Tải file']);