• Час читання ~6 хв
  • 14.12.2022

If you're building a Laravel application, package, or CLI (commі-line interface) application, you'll likely create your own custom Artisan commіs at some stage. When creating these commіs, you might want to make the output unique і stі out from the rest з the console output. To do this, you can the awesome Термінд пакет.

У цій статті ми розглянемо, що таке Termwind, як його встановити та як використовувати у своїх власних командах Artisan. Потім ми крок за кроком оновимо старий приклад команди Artisan для використання Termwind і побачимо, як це покращить результат.

Що таке Termwind?

Termwind — це пакет PHP, створений і підтримуваний Нуно Мадуро (та інші чудові учасники, такі як Франциско Мадейра), що дозволяє використовувати класи CSS, схожі на Tailwind, у вашому коді PHP, щоб додати стилі до виводу CLI.

Це чудовий інструмент для використання, якщо ви хочете зробити висновок ваших команд унікальним і виділятися з натовпу. Тому його дуже зручно використовувати, якщо ви створюєте програму CLI або пакет Laravel, який надає будь-які команди Artisan.

Він надає вам можливість створювати вихідні дані за допомогою HTML і класів, подібних до Tailwind, наприклад текст-синій-500, flex and пробіл-x-1. Ви можете переглянути повний список доступних класів у документація на пакет.

Використання

монтаж

Щоб почати використовувати Termwind у своїх програмах Laravel, вам потрібно буде встановити його за допомогою Composer, виконавши таку команду:

composer require nunomaduro/termwind

Це воно! Termwind тепер встановлено та готово до роботи.

Відображення результату за допомогою вбудованого HTML

Now that we have Termwind installed, let's take a look at how we can use it to рендерити some output to the CLI.

The quickest way to рендерити the output is to pass some HTML as a string directly to the package's render функція.

Щоб надати цьому трохи контексту, розглянемо простий приклад. Уявімо, що у нас є команда Artisan, яку ми можемо використовувати для виведення деяких статистичних даних про нашу програму Laravel. Для цієї статті ми будемо використовувати жорстко закодовану статистику, щоб ми могли зосередитися виключно на Termwind.

Отже, давайте подивимося на команду:

namespace App\Console\Commands;

use Illuminate\Console\Command;
use function Termwind\{render};

class AppStats extends Command
{
    protected $signature = 'app:stats';

    protected $description = 'Display the application stats';

    public function handle(): int
    {
        render(<<<'HTML'
            <div class="mx-2 my-1">
                <div class="space-x-1">
                    <span class="px-1 bg-blue-500 text-white">Application Info</span>
                </div>

                <div class="mt-1">
                    <span class="font-bold text-green">Totals</span>

                    <div class="flex space-x-1">
                        <span class="font-bold">Users</span>
                        <span class="flex-1 content-repeat-[.] text-gray"></span>
                        <span class="font-bold text-green">150</span>
                    </div>

                    <div class="flex space-x-1">
                        <span class="font-bold">Posts</span>
                        <span class="flex-1 content-repeat-[.] text-gray"></span>
                        <span class="font-bold text-green">200</span>
                    </div>

                    <div class="flex space-x-1">
                        <span class="font-bold">Comments</span>
                        <span class="flex-1 content-repeat-[.] text-gray"></span>
                        <span class="font-bold text-green">175</span>
                    </div>
                </div>

                <div class="mt-1">
                    <span class="font-bold text-green">Health Checks</span>

                    <div class="flex space-x-1">
                        <span class="font-bold">Mailcoach</span>
                        <i class="text-gray">Newsletter</i>
                        <span class="flex-1 content-repeat-[.] text-gray"></span>
                        <span class="font-bold text-green">CONNECTED</span>
                    </div>

                    <div class="flex space-x-1">
                        <span class="font-bold">Vonage</span>
                        <i class="text-gray">SMS</i>
                        <span class="flex-1 content-repeat-[.] text-gray"></span>
                        <span class="font-bold text-red">ERROR!</span>
                    </div>
                </div>
            </div>
        HTML);

        return self::SUCCESS;
    }
}

Наведена вище команда виведе наступне в CLI:

As you can see, we can generate some really cool output using Termwind. But having the HTML directly in the command class can become messy very quickly. It's not very readable or maintainable. For example, if we wanted to use the same стильs in other commands, we'd potentially be duplicating a lot of the shared HTML.

Однак варто зазначити, що для менших обсягів виходу цей підхід може бути ідеальним. Просто коли ви починаєте отримувати багато результатів, це може стати трохи стомлюючим для підтримки.

Termwind's стиль функція може допомогти нам згрупувати стилі разом, щоб ми могли використовувати їх у багатьох місцях. Однак це не обов’язково вирішує проблему фактичного HTML, який будує структуру виведення. Я б рекомендував перевірити style функцію в документації щоб дізнатися більше про те, як ви можете використовувати його для спрощення обслуговування.

Відображення результату за допомогою перегляду

Now that we've seen how to output some HTML directly to the CLI, let's take a look at how we can use a Blade переглянути to render the output. I prefer using this approach as it keeps the HTML separate from the command class and makes it easier to maintain and reuse across different commands.

Для початку давайте створимо новий cli каталог у наших проектах ресурси/перегляди каталог. Тут ми зберігатимемо всі представлення, які стосуються CLI.

Потім ми створимо новий app-stats.blade.php переглянути в cli каталог. Це буде вигляд, який ми використовуватимемо для візуалізації результату для нашого додаток: статистика і він міститиме HTML з нашого попереднього прикладу (усе між <<<'HTML' and HTML).

Тепер, коли у нас є HTML у представленні Blade, ми можемо оновити наш клас команд, щоб використовувати його. Ми зробимо це за допомогою view допоміжна функція для візуалізації перегляду та передачі його виводу до Termwind render функція:

namespace App\Console\Commands;

use Illuminate\Console\Command;
use function Termwind\{render};

class AppStats extends Command
{
    protected $signature = 'app:stats';

    protected $description = 'Display the application stats';

    public function handle(): int
    {
        render(view('cli.app-stats'));

        return self::SUCCESS;
    }

Як бачите, це значно полегшило розуміння та підтримку класу команд. Тепер ми можемо зосередитися на логіці команди і не хвилюватися про HTML, який захаращує цей клас.

Величезною перевагою використання цього підходу є те, що він також дозволяє нам використовувати компоненти Blade, щоб зробити наш результат ще більш придатним для повторного використання. Ми можемо створити компонент для кожного з різних розділів виводу, а потім використовувати їх у нашому поданні.

Давайте розглянемо, як ми можемо використовувати деякі компоненти Blade для покращення зручності обслуговування нашої команди.

Ми почнемо зі створення нового компоненти/кл каталог у нашому ресурси/перегляди каталог. Схожий на наш ресурси/перегляди/кл у цьому каталозі ми зберігатимемо всі наші специфічні для CLI компоненти Blade.

Ми можемо ідентифікувати дві основні частини результату нашої команди, які можна розділити на компоненти в нашому прикладі вище:

  1. Підсумки
  2. Перевірки здоров'я

Тому ми створимо компонент для кожного з них. Однак пам’ятайте, що ви можете створити стільки компонентів, скільки забажаєте, щоб відповідати потребам вашого проекту.

Почнемо зі створення нового totals.blade.php компонент в ресурси/перегляди/компоненти/клі каталог. Цей компонент використовуватиметься для відтворення підсумків для кожної статистики, яку ми маємо.

@props([
    'title',
    'value',
])
<div class="flex space-x-1">
    <span class="font-bold">{{ $title }}</span>
    <span class="flex-1 content-repeat-[.] text-gray"></span>
    <span class="font-bold text-green">{{ $value }}</span>
</div>

Як бачите, цей компонент дуже простий і має 2 різні властивості, визначені за допомогою @props Директива леза. Він приймає дві властивості, назва and значення. Це чудовий спосіб гарантувати, що ми не забудемо передати необхідні властивості компоненту.

Тепер ми також можемо створити новий підключення.blade.php компонент в ресурси/перегляди/компоненти/клі каталог:

@props([
    'title',
    'subText',
    'connected' => false,
])
<div class="flex space-x-1">
    <span class="font-bold">{{ $title }}</span>
    <i class="text-gray">{{ $subText }}</i>
    <span class="flex-1 content-repeat-[.] text-gray"></span>

    @if($connected)
        <span class="font-bold text-green">CONNECTED</span>
    @else
        <span class="font-bold text-red">ERROR!</span>
    @endif
</div>

Можливо, ви помітили, що компонент має 3 різні властивості, визначені за допомогою @props Директива леза. Це означає, що ми повинні передати a назва власність, підтекст властивість і необов'язковий підключений кожного разу, коли ми використовуємо компонент.

Як ми бачимо з нашого прикладу раніше, якщо підключений властивість встановлено на правда, компонент виведе ПІДКЛЮЧЕНО текст зеленим кольором. В іншому випадку буде виведено ПОМИЛКА! текст червоним.

Тепер, коли у нас створені та готові компоненти, ми можемо конвертувати наші ресурси/перегляди/cli/app-stats.blade.php переглянути їх використання:

<div class="mx-2 my-1">
    <div class="space-x-1">
        <span class="px-1 bg-blue-500 text-white">Application Info</span>
    </div>

    <div class="mt-1">
        <span class="font-bold text-green">Totals</span>

        <x-cli.stat title="Users" value="150" />
        <x-cli.stat title="Posts" value="200" />
        <x-cli.stat title="Comments" value="175" />
    </div>

    <div class="mt-1">
        <span class="font-bold text-green">Health Checks</span>

        <x-cli.connection title="Mailcoach" subText="Newsletter" :connected="true" />
        <x-cli.connection title="Vonage" subText="SMS" :connected="false" />
    </div>
</div>

Як бачите, HTML тепер набагато легше читати та розуміти. Нам вдалося зменшити кількість дубльованого HTML, викликавши компоненти за допомогою <x-cli.stat ... /> and <x-cli.connection ... /> Синтаксис леза. Одна річ, яка мені подобається в цьому підході, полягає в тому, що ми можемо використовувати Blade, створюючи вихідні дані CLI, ми відчуваємо себе дуже схожим на створення веб-переглядів.

Перетворення наявної команди

Тепер, коли ми побачили, як ми можемо виводити HTML до CLI за допомогою Termwind, давайте коротко розглянемо, як можна перетворити існуючу команду на використання Termwind.

Уявімо, що у нас є команда Artisan, яка виконує наступне:

  • Запитує користувача ввести пошуковий термін.
  • Пошук у базі даних для будь-яких користувачів, які мають адресу електронної пошти, яка містить пошуковий термін.
  • Виводить результати в CLI.

This is only a simple example but should give us a good chance to highlight several of the features that Termwind provides. For the sake of the example, we also won't be covering how we search the database for the користувачів, as this is not the focus of this article. But we can assume that the searchКористувачs метод у прикладі нижче поверне a Колекція of User моделі.

Наша існуюча команда може виглядати приблизно так:

namespace App\Console\Commands;

use App\Models\User;
use Illuminate\Console\Command;

final class UsersSearch extends Command
{
    protected $signature = 'users:search';

    protected $description = 'Search for users in the system';

    public function handle(): int
    {
        $searchTerm = $this->ask('Search term: ');

        $users = $this->searchUsers($searchTerm);

        $rows = $users->map(fn (User $user): array => [
            $user->name,
            $user->email,
            $user->email_verified_at ?? 'No!',
        ])->all();

        $this->info('Found '.count($users).' users');
        $this->table(['Name', 'Email', 'Approved'], $rows);

        return self::SUCCESS;
    }
}

Наведена вище команда надасть такий результат:

Якщо ми хочемо оновити команду для використання Termwind, наш клас може виглядати так:

namespace App\Console\Commands;

use App\Models\User;
use Illuminate\Console\Command;
use function Termwind\{ask, render};

final class UsersSearch extends Command
{
    protected $signature = 'users:search';

    protected $description = 'Search for users in the system';

    public function handle(): int
    {
        $searchTerm = ask(<<<HTML
            <span class="mt-1 ml-2 mr-1 bg-green px-1 text-black">
                Search term:
            </span>
        HTML);

        $users = $this->searchUsers($searchTerm);

        render(view('cli.user-search', [
            'users' => $users,
        ]));
        return self::SUCCESS;
    }
}

Давайте подивимося, що змінилося.

Як ви могли помітити, ми замінили $this->запитати зателефонуйте з Termwind's ask функція. Це забезпечить нам досвід, подібний до існуючої команди, але з додатковою перевагою можливості використовувати стиль Termwind.

Ми також замінили $this->info and $this->table викликає, переміщуючи решту виводу команди до a resources/views/cli/user-search.blade.php Вигляд леза (як ми розглядали раніше в цій статті). Як бачимо, ми пройшли $користувачів збирання в представлення точно так само, як ми могли б передати дані в веб-перегляд. Вигляд Blade виглядає так:

<div class="m-1">
    <div class="text-right mb-1 w-full">
        <span class="text-indigo-500">Found [<b>{{ $users->count() }}</b>] users</span>
    </div>

    @foreach($users as $user)
        <div>
            <div class="flex space-x-1">
                <span class="font-bold">{{ $user->name }}</span>
                <span class="text-gray">[{{ $user->email }}]</span>
                <span class="flex-1 content-repeat-[.] text-gray"></span>
                <span class="text-gray">Approved:</span>

                @if($user->email_verified_at)
                    <span class="font-bold text-green">{{ $user->email_verified_at }}</span>
                @else
                    <span class="font-bold text-red">NO!</span>
                @endif
            </div>
        </div>
    @endforeach
</div>

У файлі Blade ми відображаємо загальну кількість знайдених користувачів, а потім переглядаємо users Колекція передається до перегляду та виводить імена користувачів, електронні адреси та інформацію про те, чи вони були схвалені.

У результаті внесення цих змін команда тепер виводить наступне:

Тепер ми успішно перетворили команду Artisan на використання Termwind!

Висновок

Сподіваюся, ця стаття мала дати вам огляд того, що таке Termwind і як ви можете використовувати його для створення чудових виходів CLI для ваших команд Artisan. Тепер ви зможете використовувати свої існуючі команди та перетворювати їх для використання Termwind або навіть почати створювати нові команди з нуля.

Якщо ви хочете прочитати більше про Termwind, ви можете перевірити документація на GitHub.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Про автора CrazyBoy49z
WORK EXPERIENCE
Контакти
Ukraine, Lutsk
+380979856297