Comment définir des variables dans un modèle de lame Laravel

247

Je lis la documentation de Laravel Blade et je n'arrive pas à comprendre comment affecter des variables à l'intérieur d'un modèle pour une utilisation ultérieure. Je ne peux pas le faire {{ $old_section = "whatever" }}car cela fera écho à "quoi que ce soit" et je ne veux pas ça.

Je comprends que je peux le faire <?php $old_section = "whatever"; ?>, mais ce n'est pas élégant.

Existe-t-il une meilleure façon élégante de le faire dans un modèle Blade?

dualité_
la source
1
Vérifiez cette traction: github.com/laravel/laravel/pull/866
Spir
Ceci est souvent utile pour les tests, surtout si vous travaillez sur le modèle mais que quelqu'un d'autre travaille sur la partie PHP. Veillez simplement à supprimer la déclaration lorsque vous avez terminé les tests.
trysis
Quel est le problème de simplement faire <?php $old_section = "whatever"; ?>. Je le trouve assez lisible.
Jaime Hablutzel
@JaimeHablutzel la réponse, à mon avis, est dans la question: ce n'est pas élégant.
duality_

Réponses:

122

Il est déconseillé de le faire dans une vue donc il n'y a pas d'étiquette de lame pour cela. Si vous voulez le faire dans votre vue de lame, vous pouvez simplement ouvrir une balise php telle que vous l'avez écrite ou enregistrer une nouvelle balise de lame. Juste un exemple:

<?php
/**
 * <code>
 * {? $old_section = "whatever" ?}
 * </code>
 */
Blade::extend(function($value) {
    return preg_replace('/\{\?(.+)\?\}/', '<?php ${1} ?>', $value);
});
TLGreg
la source
9
Les variables dans les vues ont certaines utilisations. Ça a l'air super! Où serait un bon endroit pour mettre ce code?
duality_
1
Vous pouvez le mettre dans votre application / start.php ou si vous voulez plus de choses comme ça, le mettre dans un fichier séparé et l'inclure là. Laravel est très lâche de cette façon, vous pouvez même affiner un contrôleur. La seule chose que vous ayez à faire ces extensions s'étend avant le rendu de la vue.
TLGreg
19
Quel est le raisonnement pour ajouter ce code supplémentaire juste pour utiliser {?au lieu d'utiliser simplement le natif <??
Justin
1
S'il est déconseillé de le faire, existe-t-il une façon plus «appropriée» de procéder comme suit? J'ai un site où le titre est affiché dans la vue principale de l'application sous la forme {{$ title}}, qui contient un sous-système qui doit ajouter le numéro de page au titre ("Page de formulaire de demande {{$ page}}") et Je passe $ page à la vue (qui est utilisée autrement dans la vue). Je ne veux pas construire le titre dans chaque appel de contrôleur, je veux juste envoyer à la vue le numéro de page - juste au cas où un jour je voudrais changer le titre de base. J'utilise <? Php $ title = ...?> Maintenant, mais y a-t-il une manière plus correcte?
jdavidbakr
4
Les variables doivent être transmises depuis le contrôleur, non déclarées en ligne dans votre vue. Si un modèle global a besoin d'une variable, vous pouvez la définir dans un fournisseur de services stackoverflow.com/a/36780419/922522 . Si un modèle spécifique à une page a besoin d'une variable, utilisez @yield et transmettez-la à partir de la vue enfant dotée d'un contrôleur. laravel.com/docs/5.1/blade#template-inheritance
Justin
361

LARAVEL 5.5 ET PLUS

La directive lame @php n'accepte plus les balises en ligne. Utilisez plutôt la forme complète de la directive:

@php
$i = 1
@endphp

LARAVEL 5.2 ET PLUS

Vous pouvez simplement utiliser:

@php ($i = 1)

Ou vous pouvez l'utiliser dans une instruction de bloc:

@php
$i = 1
@endphp

LARAVEL 5

Étendez Blade comme ceci:

/*
|--------------------------------------------------------------------------
| Extend blade so we can define a variable
| <code>
| @define $variable = "whatever"
| </code>
|--------------------------------------------------------------------------
*/

\Blade::extend(function($value) {
    return preg_replace('/\@define(.+)/', '<?php ${1}; ?>', $value);
});

Effectuez ensuite l'une des opérations suivantes:

Solution rapide: si vous êtes paresseux, mettez simplement le code dans la fonction boot () de AppServiceProvider.php.

Solution plus agréable: créez votre propre fournisseur de services. Voir https://stackoverflow.com/a/28641054/2169147 sur la façon d'étendre la lame dans Laravel 5. C'est un peu plus de travail de cette façon, mais un bon exercice sur la façon d'utiliser les fournisseurs :)

LARAVEL 4

Vous pouvez simplement mettre le code ci-dessus au bas de app / start / global.php (ou tout autre endroit si vous pensez que c'est mieux).


Après les modifications ci-dessus, vous pouvez utiliser:

@define $i = 1

pour définir une variable.

Pim
la source
5
Agréable! Veuillez noter que vous pouvez exécuter n'importe quelle instruction php avec votre implémentation. Je le renommerais en quelque chose comme @php. Très pratique ...
igaster
Très vrai, igaster. Vous pouvez renommer 'define' en 'php' si vous le souhaitez, mais cela ouvre le piège à la surutilisation de php dans vos modèles :)
Pim
1
Merci @ C.delaFonteijne, si vous utilisez l'espace de noms (et vous devriez), le \ est en effet nécessaire. J'ai ajouté le \ dans le code ci-dessus.
Pim
1
Veuillez noter que presque votre implémentation exacte est standard depuis Laravel 5.2 . Vous pouvez l'utiliser @php(@i = 1)ou l'utiliser dans une instruction de bloc (fermer avec @endphp)
Daan
1
Je ne vois pas comment "@php" "@endphp" est "plus élégant" que "<? Php" "?>". C'est même quelques caractères de plus! Est-ce simplement parce qu'il commence par un "@" comme les autres directives Blade? Nous, les développeurs, sommes un groupe obsessionnel-compulsif! ;-)
OMA
116

Dans , vous pouvez utiliser la syntaxe de commentaire du modèle pour définir / définir des variables.

La syntaxe des commentaires est {{-- anything here is comment --}}et est rendue par moteur comme

<?php /* anything here is comment */ ?>

donc avec peu de truc on peut l'utiliser pour définir des variables, par exemple

{{-- */$i=0;/* --}}

sera rendu par comme <?php /* */$i=0;/* */ ?>qui définit la variable pour nous. Sans changer aucune ligne de code.

S'essayer à Tobemyself
la source
2
@ essayer-de-se faire +1 | Pas la meilleure pratique , mais parfait pour le piratage rapide de code dans des modèles comme avec les styles en ligne pour html.
Markus Hofmann
121
Je ne recommanderais pas de faire ce hack car quiconque regarde ce code après vous va vous haïr.
Justin
2
D'accord avec Justin, les balises de commentaire sont pour les commentaires, pour décommenter le commentaire et commencer à faire autre chose demande des ennuis
Leon
27
Ce n'est pas mieux que le vieux php<?php $i=0; ?>
gyo
3
Quel est l'intérêt de faire cela au lieu d'utiliser des balises php ?? Il n'est pas lisible (ressemble à un commentaire), nécessite plus de frappe et peut se casser avec une mise à jour du système d'analyse. Même s'il a un point, ce n'est pas la réponse à la façon de définir une variable dans un modèle de lame. Je ne sais pas ce qui ne va pas avec les électeurs, peut-être ont-ils trouvé cela si «geek»? meh ...
SuperDuck
52

Il existe une solution de contournement simple qui ne vous oblige à modifier aucun code, et cela fonctionne aussi bien dans Laravel 4.

Vous utilisez simplement un opérateur d'affectation ( =) dans l'expression passée à une @ifinstruction, au lieu (par exemple) d'un opérateur tel que ==.

@if ($variable = 'any data, be it string, variable or OOP') @endif

Ensuite, vous pouvez l'utiliser n'importe où, vous pouvez utiliser n'importe quelle autre variable

{{ $variable }}

Le seul inconvénient est que votre affectation ressemblera à une erreur pour quelqu'un qui ne sait pas que vous faites cela comme solution de contournement.

BTMPL
la source
27

Tu vas le rendre trop compliqué.

Utilisez simplement du php ordinaire

<?php $i = 1; ?>
{{$i}}

donesies.

(ou https://github.com/alexdover/blade-set semble également très simple)

Nous sommes tous un peu en train de "pirater" le système en définissant des variables dans les vues, alors pourquoi rendre le "piratage" plus compliqué qu'il ne doit l'être?

Testé à Laravel 4.

Un autre avantage est que la mise en évidence de la syntaxe fonctionne correctement (j'utilisais auparavant le hack de commentaires et c'était horrible à lire)

Sabrina Leggett
la source
21

Vous pouvez définir des variables dans le moteur de création de modèles de lame de la façon suivante:

1.
Variable générale de paramètre de bloc PHP : <?php $hello = "Hello World!"; ?>
Sortie: {{$hello}}

2.
Variable de paramètre de bloc PHP Blade : @php $hello = "Hello World!"; @endphp
Sortie: {{$hello}}

Prince Ahmed
la source
19

Depuis Laravel 5.2.23, vous avez la directive @php Blade , que vous pouvez utiliser en ligne ou comme instruction de bloc:

@php($old_section = "whatever")

ou

@php
    $old_section = "whatever"
@endphp
Daan
la source
15

Vous pouvez définir une variable dans le fichier de vue, mais elle sera imprimée telle que vous la définissez. Quoi qu'il en soit, il existe une solution de contournement. Vous pouvez définir la variable dans une section inutilisée. Exemple:

@section('someSection')
  {{ $yourVar = 'Your value' }}
@endsection

Ensuite , {{ $yourVar }}imprimera Your valuepartout où vous le souhaitez, mais vous ne recevez pas la sortie lorsque vous enregistrez la variable.

EDIT: nommer la section est obligatoire sinon une exception sera levée.

Vasile Goian
la source
Ne fonctionne pas autre chose doit être inclus Propriété non définie: Illuminate \ View \ Factory :: $ startSection (View: /home/vagrant/Code/dompetspy/resources/views/reviews/index.blade.php)
MaXi32
14

Dans Laravel 4:

Si vous vouliez que la variable accessible dans toutes vos vues, pas seulement votre modèle, View::sharesoit une excellente méthode ( plus d'informations sur ce blog ).

Ajoutez simplement ce qui suit dans app / controllers / BaseController.php

class BaseController extends Controller
{
  public function __construct()
  {                   
    // Share a var with all views
    View::share('myvar', 'some value');
  }
}

et $myvarsera désormais disponible pour toutes vos vues, y compris votre modèle.

Je l'ai utilisé pour définir des URL d'actifs spécifiques à l'environnement pour mes images.

Justin
la source
1
C'est ce que je cherchais: un excellent moyen d'éviter les appels en double dans la base de données!
clod986
Cela ne semble pas être une option dans Laravel 5?
Goddard
@Goddard Vous pouvez toujours. La syntaxe a changé cependant: stackoverflow.com/a/36780419/922522
Justin
8

Et soudain, rien n'apparaîtra. D'après mon expérience, si vous devez faire quelque chose comme ça, préparez le code HTML dans la méthode d'un modèle ou réorganisez votre code en tableaux ou quelque chose.

Il n'y a jamais qu'une seule façon.

{{ $x = 1 ? '' : '' }}
Michael J. Calkins
la source
11
Préparer le HTML dans le modèle? C'est la chose la plus laide qu'on puisse imaginer.
duality_
@duality_ Vous déclarez et modifiez des variables dans votre vue. J'ai dit que vous organisiez probablement mal votre code. Architecte Lrn 2.
Michael J.Calkins
3
Bien sûr, Michael ... Ces variables ne sont pas des variables telles que $users = ..., mais quelque chose le long des lignes $css_class = ..., donc strictement des variables de conception qui n'appartiennent pas au modèle ou au contrôleur, car elles sont déterminées par le concepteur.
duality_
2
si vous devez suivre cette voie, je préfère la solution la plus simple et la plus élégante: {{''; $ x = 1}}
Daniel
6

Je vais étendre la réponse donnée par @Pim.

Ajoutez ceci à la méthode de démarrage de votre AppServiceProvider

<?php
/*
|--------------------------------------------------------------------------
| Extend blade so we can define a variable
| <code>
| @set(name, value)
| </code>
|--------------------------------------------------------------------------
*/

Blade::directive('set', function($expression) {
    list($name, $val) = explode(',', $expression);
    return "<?php {$name} = {$val}; ?>";
});

De cette façon, vous n'exposez pas la possibilité d'écrire une expression php.

Vous pouvez utiliser cette directive comme:

@set($var, 10)
@set($var2, 'some string')
Carson Evans
la source
5

Dans Laravel 5.1, 5.2 :

https://laravel.com/docs/5.2/views#sharing-data-with-all-views

Vous devrez peut-être partager un élément de données avec toutes les vues rendues par votre application. Vous pouvez le faire en utilisant la méthode de partage de la fabrique de vues. En règle générale, vous devez passer des appels à partager dans la méthode de démarrage d'un fournisseur de services. Vous êtes libre de les ajouter à AppServiceProvider ou de générer un fournisseur de services distinct pour les héberger.

Modifier le fichier: /app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

class AppServiceProvider extends ServiceProvider
{        
    public function boot()
    {
        view()->share('key', 'value');
    }

    public function register()
    {
        // ...
    }
}
Justin
la source
5

Vous pouvez utiliser le package que j'ai publié: https://github.com/sineld/bladeset

Ensuite, vous définissez facilement votre variable:

@set('myVariable', $existing_variable)

// or

@set("myVariable", "Hello, World!")
Sinan Eldem
la source
3

Quant à ma manière élégante est comme la suivante

{{ ''; $old_section = "whatever"; }}

Et faites simplement écho à votre $old_sectionvariable.

{{ $old_section }}
Définir Kyar Wa Lar
la source
3

Si vous avez PHP 7.0:

Le moyen le plus simple et le plus efficace consiste à attribuer des parenthèses à l'intérieur .

La règle est simple: utilisez-vous votre variable plusieurs fois? Déclarez-le ensuite la première fois qu'il est utilisé entre parenthèses, gardez votre calme et continuez.

@if(($users = User::all())->count())
  @foreach($users as $user)
    {{ $user->name }}
  @endforeach
@else
  There are no users.
@endif

Et oui, je sais @forelse , c'est juste une démo.

Étant donné que vos variables sont désormais déclarées au fur et à mesure de leur utilisation, aucune solution de contournement n'est nécessaire.

Jonathan
la source
2

Je ne pense pas que vous puissiez - mais là encore, ce type de logique devrait probablement être géré dans votre contrôleur et transmis à la vue déjà définie.

Darren Craig
la source
6
Certaines variables sont strictement réservées aux vues. $previous_group_name, $separator_printedEtc.
duality_
2
Si ce n'est que pour les vues, vous devez simplement le passer à la vue du contrôleur. Si vous le souhaitez disponible pour toutes les vues, voir ma réponse ci-dessus en utilisant app/controllers/BaseController.php.
Justin
1
J'utilise plusieurs tableaux pour envoyer toutes mes données $ à la vue
Hos Mercury
2

Attribuer une variable au modèle de lame, voici les solutions

Nous pouvons utiliser la <?php ?>balise dans la page de lame

<?php $var = 'test'; ?>
{{ $var }

OU

Nous pouvons utiliser le commentaire de lame avec une syntaxe spéciale

{{--*/ $var = 'test' /*--}}
{{ $var }}
Nikunj K.
la source
1

Le piratage des commentaires n'est pas une manière très lisible de le faire. Les éditeurs le colorieront également en tant que commentaire et quelqu'un pourrait le manquer en parcourant le code.

Essayez quelque chose comme ceci:

{{ ''; $hello = 'world' }}

Il se compilera en:

<?php echo ''; $hello = 'world'; ?>

... et faites le devoir et ne faites aucun écho.

rotaercz
la source
1

Il est préférable de s'entraîner à définir une variable dans le contrôleur, puis de passer à l'affichage en utilisant compact()ou->with() méthode.

Sinon, #TLGreg a donné la meilleure réponse.

Mandeep Gill
la source
1

Il existe une très bonne extension pour les extensions radic / blade de Blade . Après l'avoir ajouté, vous pouvez utiliser @set (nom_variable, valeur_variable)

@set(var, 33)
{{$var}}
belov91
la source
1

Je cherchais un moyen d'attribuer une valeur à une clé et de l'utiliser plusieurs fois à mon avis. Dans ce cas, vous pouvez utiliser @section{"key", "value"}en premier lieu, puis appeler @yield{"key"}pour afficher la valeur à d'autres endroits de votre vue ou de son enfant.

Hafez Divandari
la source
0

À mon avis, il serait préférable de conserver la logique dans le contrôleur et de la transmettre à la vue à utiliser. Cela peut être fait de deux manières en utilisant la méthode 'View :: make'. J'utilise actuellement Laravel 3 mais je suis sûr que c'est la même chose dans Laravel 4.

public function action_hello($userName)
{
    return View::make('hello')->with('name', $userName);
}

ou

public function action_hello($first, $last)
{
    $data = array(
        'forename'  => $first,
        'surname' => $last
    );
    return View::make('hello', $data);
}

La méthode «avec» est chaînable. Vous utiliseriez alors ce qui précède comme ceci:

<p>Hello {{$name}}</p>

Plus d'informations ici:

http://three.laravel.com/docs/views

http://codehappy.daylerees.com/using-controllers

Robert Brisita
la source
La logique de présentation est mieux conservée dans la vue. Parfois, vous devez créer une variable à partir de la vue. par exemple pour formater une date. $format='Y-m-d H:i:s';de cette façon, vous pouvez réutiliser ce format dans la vue. Cela n'appartient certainement pas au contrôleur. Cela dit, en réponse à la question ... Il n'y a rien de mal avec les <?php ?>balises.
Gravy
0

J'avais une question similaire et j'ai trouvé ce que je pense être la bonne solution avec View Composers

Les compositeurs de vues vous permettent de définir des variables à chaque appel d'une certaine vue, et il peut s'agir de vues spécifiques ou de modèles de vues entiers. Quoi qu'il en soit, je sais que ce n'est pas une réponse directe à la question (et 2 ans trop tard) mais cela semble être une solution plus gracieuse que de définir des variables dans une vue avec lame.

View::composer(array('AdminViewPath', 'LoginView/subview'), function($view) {
    $view->with(array('bodyClass' => 'admin'));
});
creusé
la source
0

laravel 5 vous pouvez facilement le faire. voir ci-dessous

{{--*/ @$variable_name = 'value'  /*--}}
tapos ghosh
la source
0

Vous pouvez étendre la lame en utilisant la méthode d'extension comme indiqué ci-dessous.

Blade::extend(function($value) {
    return preg_replace('/\@var(.+)/', '<?php ${1}; ?>', $value);
});

après cela, initialisez les variables comme suit.

@var $var = "var"
Lakitha Dias
la source
-1

fonctionne dans toutes les versions de lame.

{{--*/  $optionsArray = ['A', 'B', 'C', 'D','E','F','G','H','J','K'] /*--}}
Bakhtawar GIll
la source