Xây dựng CLI Dashboard tương tác với Laravel Prompts
Quản lý blog dựa trên file bao gồm việc tạo file, định dạng ngày tháng, và quản lý frontmatter. Mặc dù tôi có thể làm điều này thủ công trong VS Code, việc có một công cụ CLI khiến nó cảm giác như một CMS thực sự.
Laravel gần đây đã giới thiệu Laravel Prompts, một package giúp xây dựng form CLI đẹp và dễ dàng. Hãy cùng xây dựng lệnh php artisan blog:manage.
Thiết lập ban đầu
Chúng ta muốn một lệnh cho phép:
- Tạo bài viết mới.
- Liệt kê các bản draft gần đây.
- Publish một bản draft.
Tạo Command
Đầu tiên, tạo command:
php artisan make:command ManageBlog
Triển khai
Chúng ta sẽ sử dụng select, text, confirm, và multiselect từ namespace Laravel\Prompts.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Carbon\Carbon;
use function Laravel\Prompts\select;
use function Laravel\Prompts\text;
use function Laravel\Prompts\confirm;
use function Laravel\Prompts\multiselect;
use function Laravel\Prompts\info;
class ManageBlog extends Command
{
protected $signature = 'blog:manage';
protected $description = 'Interactive blog management dashboard';
public function handle()
{
$action = select(
label: 'What would you like to do?',
options: [
'create' => 'Create a new post',
'view' => 'View drafts',
'exit' => 'Exit',
]
);
match ($action) {
'create' => $this->createPost(),
'view' => $this->viewDrafts(),
'exit' => $this->info('Goodbye!'),
};
}
protected function createPost()
{
$title = text('Post Title', required: true, placeholder: 'My Awesome Post');
$slug = text(
label: 'Slug',
default: Str::slug($title),
validate: fn (string $value) => match (true) {
strlen($value) < 3 => 'The slug must be at least 3 characters.',
default => null
}
);
$tags = multiselect(
label: 'Select Tags',
options: ['laravel', 'php', 'javascript', 'css', 'devops', 'testing'],
scroll: 5
);
$isDraft = confirm('Save as draft?', default: false);
$date = Carbon::now()->format('Y-m-d');
$filename = "{$date}-{$slug}.md";
$path = base_path("content/posts/" . Carbon::now()->format('Y'));
// Ensure directory exists
if (!is_dir($path)) {
mkdir($path, 0755, true);
}
$content = <<<EOT
---
title: "{$title}"
date: {$date}
description: ""
tags: {$this->formatTags($tags)}
draft: {$this->boolToString($isDraft)}
---
Write your content here...
EOT;
file_put_contents("$path/$filename", $content);
info("Post created at: $path/$filename");
}
protected function formatTags(array $tags): string
{
return '["' . implode('", "', $tags) . '"]';
}
protected function boolToString(bool $val): string
{
return $val ? 'true' : 'false';
}
protected function viewDrafts()
{
// Implementation for scanning standard directory for `draft: true`
info("Feature coming soon...");
}
}
Tại sao chọn Laravel Prompts?
1. Validation
Validation diễn ra inline. Bạn không cần submit form để thấy mình đã mắc lỗi.
2. Select có thể tìm kiếm
Nếu bạn có 50 tag, multiselect cho phép bạn gõ để lọc chúng. Đây là cải tiến UI lớn so với input CLI tiêu chuẩn.
3. Tính nhất quán
Giao diện khớp với installer của Laravel và các công cụ ecosystem khác, khiến các công cụ nội bộ tùy chỉnh của bạn cảm giác "chính thức".
Các bước tiếp theo
Bạn có thể mở rộng điều này để:
- Chạy grammar checker trên nội dung file.
- Tự động mở file mới trong VS Code sử dụng
exec("code $path"). - Tạo AI summary sử dụng LLM API cho trường description.
Công cụ CLI không nhất thiết phải là các argument xấu xí. Với Prompts, chúng có thể trở nên thú vị khi sử dụng.