web-dev-qa-db-fra.com

Y a-t-il un moyen de compiler un modèle de lame à partir d'une chaîne?

Comment puis-je compiler un modèle de lame à partir d'une chaîne plutôt que d'un fichier d'affichage, comme le code ci-dessous:

<?php
$string = '<h2>{{ $name }}</h2>';
echo Blade::compile($string, array('name' => 'John Doe')); 
?>

http://paste.laravel.com/ujl

27
Tee Plus

J'ai trouvé la solution en étendant le bladecompiler.

<?php namespace Laravel\Enhanced;

use Illuminate\View\Compilers\BladeCompiler as LaravelBladeCompiler;

class BladeCompiler extends LaravelBladeCompiler {

    /**
     * Compile blade template with passing arguments.
     *
     * @param string $value HTML-code including blade
     * @param array $args Array of values used in blade
     * @return string
     */
    public function compileWiths($value, array $args = array())
    {
        $generated = parent::compileString($value);

        ob_start() and extract($args, EXTR_SKIP);

        // We'll include the view contents for parsing within a catcher
        // so we can avoid any WSOD errors. If an exception occurs we
        // will throw it out to the exception handler.
        try
        {
            eval('?>'.$generated);
        }

        // If we caught an exception, we'll silently flush the output
        // buffer so that no partially rendered views get thrown out
        // to the client and confuse the user with junk.
        catch (\Exception $e)
        {
            ob_get_clean(); throw $e;
        }

        $content = ob_get_clean();

        return $content;
    }

}
16
Tee Plus

Je n'utilise pas la lame de cette façon, mais je pensais que la méthode de la compilée n'accepte qu'une vue comme argument.

Peut-être que vous cherchez:

Blade::compileString()
4
Hexodus

Je viens de tomber sur la même exigence! Pour moi, je devais chercher un modèle de lame stocké dans dB et le rendre pour envoyer des notifications par courrier électronique.

Je l'ai fait dans laravel 5,8 par type d'extension \Illuminate\View\View. Donc, fondamentalement, j'ai créé la classe ci-dessous et l'a nommé StringBlade (je n'ai pas pu trouver un nom de nom de meilleur nom: /)

<?php

namespace App\Central\Libraries\Blade;

use Illuminate\Filesystem\Filesystem;

class StringBlade implements StringBladeContract
{
    /**
     * @var Filesystem
    */
    protected $file;

    /**
     * @var \Illuminate\View\View|\Illuminate\Contracts\View\Factory
    */
    protected $viewer;

    /**
     * StringBlade constructor.
     *
     * @param Filesystem $file
     */
    public function __construct(Filesystem $file)
    {
        $this->file = $file;
        $this->viewer = view();
    }

    /**
     * Get Blade File path.
     *
     * @param $bladeString
     * @return bool|string
     */
    protected function getBlade($bladeString)
    {
        $bladePath = $this->generateBladePath();

        $content = \Blade::compileString($bladeString);

        return $this->file->put($bladePath, $content)
            ? $bladePath
            : false;
    }

    /**
     * Get the rendered HTML.
     *
     * @param $bladeString
     * @param array $data
     * @return bool|string
     */
    public function render($bladeString, $data = [])
    {
        // Put the php version of blade String to *.php temp file & returns the temp file path
        $bladePath = $this->getBlade($bladeString);

        if (!$bladePath) {
            return false;
        }

        // Render the php temp file & return the HTML content
        $content = $this->viewer->file($bladePath, $data)->render();

        // Delete the php temp file.
        $this->file->delete($bladePath);

        return $content;
    }

    /**
     * Generate a blade file path.
     *
     * @return string
     */
    protected function generateBladePath()
    {
        $cachePath = rtrim(config('cache.stores.file.path'), '/');
        $tempFileName = sha1('string-blade' . microtime());
        $directory = "{$cachePath}/string-blades";

        if (!is_dir($directory)) {
            mkdir($directory, 0777);
        }

        return "{$directory}/{$tempFileName}.php";
    }
}

Comme vous pouvez l'avoir déjà vu de ce qui précède, vous trouverez ci-dessous les étapes suivies:

  1. A d'abord converti la corde de lame en équivalent PHP à l'aide de \Blade::compileString($bladeString).
  2. Maintenant, nous devons le stocker dans un fichier physique. Pour ce stockage, le répertoire cache-cache est utilisé - storage/framework/cache/data/string-blades/
  3. Maintenant, nous pouvons demander \Illuminate\View\Factory Méthode natif 'Fichier ()' pour compiler et rendre ce fichier.
  4. Supprimer le fichier Temp immédiatement (dans mon cas, je n'avais pas besoin de garder le fichier équivalent PHP, probablement identique pour vous aussi)

Et enfin j'ai créé une -façade dans A composer fichier auto-chargé pour une utilisation facile comme ci-dessous:

<?php

if (! function_exists('string_blade')) {

    /**
     * Get StringBlade Instance or returns the HTML after rendering the blade string with the given data.
     *
     * @param string $html
     * @param array $data
     * @return StringBladeContract|bool|string
     */
    function string_blade(string $html, $data = [])
    {
        return !empty($html)
            ? app(StringBladeContract::class)->render($html, $data)
            : app(StringBladeContract::class);
    }
}

Maintenant, je peux l'appeler de n'importe où comme ci-dessous:

<?php

$html = string_blade('<span>My Name is {{ $name }}</span>', ['name' => 'Nikhil']);

// Outputs HTML
// <span>My Name is Nikhil</span>

J'espère que cela aide quelqu'un ou au moins peut-être inciter quelqu'un à réécrire de manière meilleure.

À votre santé!

4
nikhil_

C'est une vieille question. Mais j'ai trouvé un paquet qui facilite le travail.

compilateur de chaîne de lame de Laravel Rend les modèles de lame de la valeur de la chaîne. Vérifiez la documentation sur la manière d'installer le package.

Voici un exemple:

$template = '<h1>{{ $name }}</h1>';  // string blade template

return view (['template' => $template], ['name' => 'John Doe']);

Remarque: Ce package n'est pas compatible avec le Laravel 5.7

2
Raghavendra N