Site non compatible avec cette vieillerie d'Internet Explorer. Pour une expérience complète, voir la liste des navigateurs supportés.
Thumbnail

 Memo Générateur de twig via invite de commandes sous Symfony 4

Premier test avec la création de commande sous Symfony 4.


Post-it | Symfony

Auteur : Guillaume M.
Créé le : 12 Jan 2020
Dernière mise à jour : 24 Feb 2021

Description


Premier essai avec la création d'invite de commandes personnalisées sous Symfony 4.3 que voici :

php bin/console ox:create-template

Que fait cette commande ? Et bien celle-ci permet de générer un fichier *.html.twig à l'endroit où on le souhaite dans l'arborescence du dossier templates de Symfony.

Voici un exemple en action :

PS C:\wamp64\www\TwigGenFile> php bin/console ox:create-template

====================================================================================
| The command automatically create a 'templates/' folder if not exists             |
| All actions will automatically take place in this folder                         |
====================================================================================

Type a name for the twig file (e.g. super-template) :
> product     

Do you need/have a specific folder for this file ? (y/n) [default : n]
y             

Folder name (e.g. my_folder or my/folder/path) :
> admin/product/

Template file created : templates/admin/product/product.html.twig

Dans un premier temps, la commande informe que le dossier templates est créé si il n'existe car les actions de la commande se passe automatiquemet à l'intérieur de celui-ci.

Ensuite le nom du fichier qui sera généré est demandé.

Puis la commande demande si il faut le placer dans un dossier spécifique, si le chemin saisi n'existe pas, le(s) dossier(s) sera crée automatiquement. Si aucun chemin n'est choisi alors le fichier sera généré à la racine du dossier templates.

Pour finir, le fichier est généré à l'endroit indiqué :

{# templates/admin/product.html.twig #}
{% extends 'base.html.twig' %}

{% block title %}Hello world{% endblock %}

{% block body %}
    <h1>Hello world</h1>
    <p>How are you today ?</p>
{% endblock %}

 

Code Source


<?php

// src/Command/TwigGenCommand.php

namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;

/**
 * Create a twig file with command prompt
 * @author Guillaume M.
 */
class TwigGenCommand extends Command
{
    protected static $defaultName = "ox:create-template";
    protected $fileName = "templates/";

    const TOWRITE =
        "{% extends 'base.html.twig' %}\n" .
        "\n" .
        "{% block title %}Hello world{% endblock %}\n" .
        "\n" .
        "{% block body %}\n" .
        "    <h1>Hello world</h1>\n" .
        "    <p>How are you today ?</p>\n" .
        "{% endblock %}\n"
    ;

    protected function configure(): void
    {
        // Command arg(s)
        $this
            ->addArgument("twigname", InputArgument::OPTIONAL, "The name of the twig file")
        ;
        // Create the templates dir if not exists
        $this->createDir("templates");
    }

    protected function interact(InputInterface $input, OutputInterface $output): void
    {
        // First output: Informations about the command
        $output->writeln([
            "",
            "<info>====================================================================================",
            "| <fg=cyan>The command automatically create a 'templates/' folder if not exists</>             |",
            "| <fg=cyan>All actions will automatically take place in this folder</>                         |",
            "====================================================================================</info>",
        ]);

        // Ask for twig file name
        $twigName = $input->getArgument("twigname");
        $helper = $this->getHelper("question");
        if(!$twigName){
            $question = new Question("\n<info>Type a name for the twig file (e.g. super-template) :</info>\n> ");
            $twigName = $helper->ask($input, $output, $question);
        }
        // Ask for path if need or have a specific folder in templates folder
        $specificFolder = "";
        $question = new ConfirmationQuestion("\n<info>Do you need/have a specific folder for this file ? (y/n)</info> [default : <comment>n</comment>]\n");
        $response = $helper->ask($input, $output, $question);
        if($response === true){
            $question = new Question("\n<info>Folder name (e.g. my_folder or my/folder/path) :</info>\n> ");
            $specificFolder .= $helper->ask($input, $output, $question);
            $this->generateSpecificFolderPath($specificFolder);
        }

        // Set the final fileName
        $this->fileName .= $twigName . ".html.twig";

        if(file_exists($this->fileName)){
            // If file already exists, ask for continue (because output file stream overwrite the file)
            $question = new ConfirmationQuestion("\n<info>the file " . $this->fileName . " already exists, do you really want to continue (file will be overwritten)  ? (y/n)</info> [default : <comment>n</comment>]\n");
            $response = $helper->ask($input, $output, $question);
            if(!$response){
                $output->writeln([
                    "",
                    "<info>Command canceled</info>",
                    ""
                ]);
                die();
            }
        }
    }

    protected function execute(InputInterface $input, OutputInterface $output): void
    {
        // Open output file stream and write in
        $ofs = fopen($this->fileName, "w");
        fwrite($ofs, "{# " . $this->fileName  . " #}\n" . self::TOWRITE);
        fclose($ofs);

        // Output result (fileName)
        $output->writeln([
            "",
            "Template file created : <comment>" . $this->fileName . "</comment>",
        ]);
    }

    //////////////////////////////////////////////
    //              HELPERS                     //
    //////////////////////////////////////////////

    /**
     * Test if directory exists and create it if not
     * 
     * @param string $dirname The dir name to create
     * @return void
     * @throws Exception If folder creation fail
     */
    protected function createDir(string $dirname): void
    {
        if(!file_exists($dirname)){
            if(!mkdir($dirname)){
                throw new \Exception("Error while creating " . $dirname . " directory");
            }
        }
    }

    /**
     * Create directories from a given path and format the fileName
     * 
     * @param string $specificFolder Represents the path where the twig file will be generated
     * @return void
     */
    protected function generateSpecificFolderPath($specificFolder): void
    {
        $newPath = $this->fileName;
        $exploded = explode("/", $specificFolder);
        for($i = 0; $i < count($exploded); $i++){
            if($exploded[$i] !== ""){
                $newPath .= $exploded[$i] . "/";
                $this->createDir($newPath);
            }
        }
        $this->fileName = $newPath;
    }
}

Cette commande est un premier jet, cela m'a permis d'entrevoir le système de création de commande sous Symfony 4.3 et d'autres s'ajouteront certainement à ma collection selon les besoins rencontrés au fil du temps.