• Czas czytania ~12 min
  • 14.12.2022

If you're building a Laravel application, package, or CLI (commoraz-line interface) application, you'll likely create your own custom Artisan commorazs at some stage. When creating these commorazs, you might want to make the output unique oraz storaz out from the rest z the console output. To do this, you can the awesome Termwind pakiet.

W tym artykule przyjrzymy się, czym jest Termwind, jak go zainstalować i jak używać go we własnych poleceniach Artisan. Następnie krok po kroku zaktualizujemy starą przykładową komendę Artisan, aby używać Termwind i zobaczymy, jak poprawia to wydajność.

Co to jest Termwind?

Termwind to pakiet PHP stworzony i utrzymywany przez Nuno Maduro (i inni niesamowici autorzy, tacy jak Franciszek Madera), który umożliwia używanie klas CSS podobnych do Tailwind w kodzie PHP w celu dodania stylów do danych wyjściowych CLI.

To świetne narzędzie, jeśli chcesz, aby dane wyjściowe Twoich poleceń wyglądały wyjątkowo i wyróżniały się z tłumu. Jest więc bardzo przydatny, jeśli budujesz aplikację CLI lub pakiet Laravel, który udostępnia dowolne polecenia Artisan.

Zapewnia możliwość budowania danych wyjściowych przy użyciu HTML i klas podobnych do Tailwind, takich jak tekst-niebieski-500, przewód and spacja-x-1. Możesz sprawdzić pełną listę dostępnych klas w package's dokumentacja.

Stosowanie

Instalacja

Aby rozpocząć korzystanie z Termwind w swoich aplikacjach Laravel, musisz zainstalować go za pomocą Composer, uruchamiając następujące polecenie:

composer require nunomaduro/termwind

Otóż ​​to! Termwind jest teraz zainstalowany i gotowy do pracy.

Wyświetlanie danych wyjściowych przy użyciu wbudowanego kodu HTML

Now that we have Termwind installed, let's take a look at how we can use it to renderowanieowanie some output to the CLI.

Najszybszym sposobem renderowania danych wyjściowych jest przekazanie kodu HTML jako ciągu znaków bezpośrednio do pakietu render funkcjonować.

Aby nadać temu nieco kontekstu, spójrzmy na prosty przykład. Wyobraźmy sobie, że mamy polecenie Artisan, którego możemy użyć do wygenerowania statystyk dotyczących naszej aplikacji Laravel. Na potrzeby tego artykułu będziemy używać zakodowanych na stałe statystyk, abyśmy mogli skupić się wyłącznie na Termwind.

Spójrzmy więc na polecenie:

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;
    }
}

Powyższe polecenie wyświetli następujące informacje w 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 styls in other commands, we'd potentially be duplicating a lot of the shared HTML.

Warto jednak zauważyć, że w przypadku mniejszych ilości danych wyjściowych takie podejście może być całkowicie w porządku. Tylko wtedy, gdy zaczynasz mieć dużo danych wyjściowych, utrzymanie może stać się nieco uciążliwe.

Termwinda styl może nam pomóc w grupowaniu stylów, abyśmy mogli ich ponownie używać w wielu miejscach. Jednak niekoniecznie rozwiązuje to problem rzeczywistego kodu HTML, który buduje strukturę danych wyjściowych. Polecam sprawdzić tzw style funkcję w dokumentacji aby dowiedzieć się więcej o tym, jak możesz go użyć, aby uprościć konserwację.

Wyświetlanie danych wyjściowych za pomocą widoku

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 pogląd 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.

Na początek utwórzmy nowy cli katalog w naszym projects zasoby/widoki informator. Tutaj będziemy przechowywać wszystkie nasze widoki specyficzne dla CLI.

Następnie utworzymy nowy app-stats.blade.php widok w cli informator. To będzie widok, którego użyjemy do renderowania danych wyjściowych dla naszego aplikacja: statystyki polecenie i będzie zawierało kod HTML z naszego poprzedniego przykładu (wszystko pomiędzy <<<'HTML' and HTML).

Teraz, gdy mamy kod HTML w widoku Blade, możemy zaktualizować naszą klasę poleceń, aby go używać. Zrobimy to za pomocą view pomocnika, aby renderować widok i przekazywać jego dane wyjściowe do Termwind render funkcjonować:

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;
    }

Jak widać, znacznie ułatwiło to zrozumienie i utrzymanie klasy poleceń. Możemy teraz skupić się na logice polecenia i nie martwić się o zaśmiecanie tej klasy przez kod HTML.

Ogromną korzyścią wynikającą z zastosowania tego podejścia jest to, że pozwala nam ono również wykorzystywać komponenty Blade, aby nasze wyniki były jeszcze bardziej przydatne do ponownego wykorzystania. Możemy utworzyć komponent dla każdej z różnych sekcji danych wyjściowych, a następnie użyć ich w naszym widoku.

Przyjrzyjmy się, jak możemy wykorzystać niektóre komponenty Blade, aby poprawić łatwość konserwacji naszego polecenia.

Zaczniemy od utworzenia nowego komponenty/kli directory in our zasoby/widoki informator. Podobny do naszego zasoby/widoki/cli katalog, w którym będziemy przechowywać wszystkie nasze komponenty Blade specyficzne dla CLI.

W powyższym przykładzie możemy zidentyfikować dwie główne części danych wyjściowych naszego polecenia, które można podzielić na komponenty:

  1. Sumy
  2. Kontrole stanu zdrowia

Stworzymy więc komponent dla każdego z nich. Pamiętaj jednak, że możesz stworzyć tyle komponentów, ile chcesz, aby pasowały do ​​potrzeb twojego projektu.

Zacznijmy od utworzenia nowego totals.blade.php składnik w zasoby/widoki/komponenty/cli informator. Ten komponent będzie używany do renderowania sum dla każdej posiadanej statystyki.

@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>

Jak widać, ten komponent jest bardzo prosty i ma 2 różne właściwości zdefiniowane za pomocą @rekwizyty Dyrektywa ostrza. Akceptuje dwie właściwości, tytuł and wartość. To świetny sposób, aby upewnić się, że nie zapomnimy przekazać żadnych wymaganych właściwości do komponentu.

Teraz możemy również utworzyć nowy połączenie.blade.php składnik w zasoby/widoki/komponenty/cli informator:

@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>

Być może zauważyłeś, że komponent ma 3 różne właściwości zdefiniowane za pomocą @rekwizyty Dyrektywa ostrza. Wymusza to, że musimy przekazać a tytuł własność, podtekst właściwość i opcjonalne połączony właściwość za każdym razem, gdy używamy komponentu.

Jak widać z naszego wcześniejszego przykładu, jeśli plik połączony właściwość jest ustawiona na PRAWDA, komponent wyświetli plik POŁĄCZONY tekst na zielono. W przeciwnym razie wyprowadzi plik BŁĄD! tekst na czerwono.

Teraz, gdy mamy utworzone i gotowe komponenty, możemy przekonwertować nasz zasoby/widoki/cli/app-stats.blade.php zobacz, jak z nich korzystać:

<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>

Jak widać, kod HTML jest teraz znacznie łatwiejszy do odczytania i zrozumienia. Udało nam się zmniejszyć ilość zduplikowanego kodu HTML, wywołując komponenty using <x-cli.stat ... /> and <x-cli.połączenie ... /> Składnia ostrza. Jedną z rzeczy, które podobają mi się w tym podejściu, jest to, że dzięki możliwości korzystania z Blade’a tworzenie danych wyjściowych CLI jest bardzo podobne do tworzenia widoków internetowych.

Konwersja istniejącego polecenia

Teraz, gdy widzieliśmy, jak możemy wyświetlać HTML do CLI za pomocą Termwind, przyjrzyjmy się pokrótce, jak możemy przekonwertować istniejące polecenie, aby używało Termwind.

Wyobraźmy sobie, że mamy polecenie Artisan, które wykonuje następujące czynności:

  • Pyta użytkownika o wyszukiwane hasło.
  • Searches the database for any użytkownicy that have an email address that contains the search term.
  • Wysyła wyniki do CLI.

To tylko prosty przykład, ale powinien dać nam dobrą szansę na podkreślenie kilku funkcji, które zapewnia Termwind. Na potrzeby przykładu nie będziemy również omawiać sposobu przeszukiwania bazy danych pod kątem użytkowników, ponieważ nie jest to tematem tego artykułu. Ale możemy założyć, że searchUżytkowniks metoda w poniższym przykładzie zwróci a Kolekcja of User modele.

Nasze istniejące polecenie może wyglądać mniej więcej tak:

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;
    }
}

Powyższe polecenie dałoby następujące dane wyjściowe:

Gdybyśmy chcieli zaktualizować polecenie, aby używało Termwind, nasza klasa mogłaby wyglądać tak:

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;
    }
}

Przyjrzyjmy się, co się zmieniło.

Jak zapewne zauważyliście, wymieniliśmy plik $this->zapytać się zadzwoń z Termwind ask funkcjonować. Zapewni nam to doświadczenie podobne do istniejącego polecenia, ale z dodatkową korzyścią w postaci możliwości korzystania ze stylu Termwind.

Wymieniliśmy również tzw $to->informacje and $to->tabela wywołań, przenosząc resztę danych wyjściowych polecenia do a zasoby/widoki/cli/user-search.blade.php Widok ostrza (jak omówiliśmy wcześniej w tym artykule). Jak widać, minęliśmy $użytkowników kolekcji do widoku w dokładnie taki sam sposób, w jaki moglibyśmy przekazać dane do widoku internetowego. Widok Blade'a wygląda tak:

<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>

W pliku Blade wyświetlamy całkowitą liczbę znalezionych użytkowników, a następnie przeglądamy plik users Kolekcja przekazywana do widoku i wyświetlająca nazwy użytkowników, adresy e-mail oraz informacje o tym, czy zostały zatwierdzone.

W wyniku wprowadzenia tych zmian polecenie wyświetla teraz następujące informacje:

Pomyślnie przekonwertowaliśmy polecenie Artisan, aby używało Termwind!

Wniosek

Mamy nadzieję, że ten artykuł powinien dać ci przegląd tego, czym jest Termwind i jak możesz go używać do tworzenia niesamowitych wyjść CLI dla twoich poleceń Artisan. Powinieneś teraz być w stanie wziąć istniejące polecenia i przekonwertować je, aby używały Termwind, a nawet rozpocząć tworzenie nowych poleceń od podstaw.

Jeśli chcesz przeczytać więcej o Termwind, możesz sprawdzić documentation na GitHubie.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

O

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...

O autorze CrazyBoy49z
WORK EXPERIENCE
Kontakt
Ukraine, Lutsk
+380979856297