Come impostare le variabili in un modello di lama Laravel


248

Sto leggendo la documentazione di Laravel Blade e non riesco a capire come assegnare variabili all'interno di un modello da utilizzare in seguito. Non posso farlo {{ $old_section = "whatever" }}perché questo farà eco "qualunque cosa" e non lo voglio.

Capisco che posso fare <?php $old_section = "whatever"; ?>, ma non è elegante.

Esiste un modo migliore ed elegante per farlo in un modello Blade?



Questo è spesso utile per i test, specialmente se stai lavorando sul modello ma qualcun altro lavora sulla parte PHP. Fai solo attenzione a rimuovere la dichiarazione al termine del test.
trysis

Cosa c'è di sbagliato nel fare semplicemente <?php $old_section = "whatever"; ?>. Lo trovo abbastanza leggibile.
Jaime Hablutzel,

@JaimeHablutzel la risposta, secondo me, è nella domanda: non è elegante.
dualità_

Risposte:


122

È sconsigliato farlo in una vista, quindi non esiste un tag blade per questo. Se vuoi farlo nella vista della lama, puoi semplicemente aprire un tag php mentre lo hai scritto o registrare un nuovo tag lama. Solo un esempio:

<?php
/**
 * <code>
 * {? $old_section = "whatever" ?}
 * </code>
 */
Blade::extend(function($value) {
    return preg_replace('/\{\?(.+)\?\}/', '<?php ${1} ?>', $value);
});

9
Le variabili nelle viste hanno alcuni usi. Questo sembra fantastico! Dove sarebbe un buon posto per mettere questo codice?
dualità_

1
Puoi metterlo nella tua applicazione / start.php o se avrai più cose come questo, mettilo in un file separato e includilo lì. Laravel è molto libero in questo modo, potresti persino sminuire un controller. L'unica cosa che devi fare si estende prima che la vista venga renderizzata.
TLGreg

19
Qual è il ragionamento per l'aggiunta di questo codice extra solo per usare {?invece di usare solo il nativo <??
Giustino,

1
Se è scoraggiato, c'è un modo più "corretto" per fare quanto segue? Ho un sito in cui il titolo viene visualizzato nella vista dell'app principale come {{$ title}}, che contiene un sottosistema che deve aggiungere il numero di pagina al titolo ("Pagina del modulo di domanda {{$ page}}") e Sto passando $ page alla vista (che altrimenti viene utilizzata nella vista). Non voglio creare il titolo in ogni chiamata del controller, voglio solo inviare alla vista il numero di pagina - nel caso in cui un giorno voglio cambiare il titolo di base. Sto usando <? Php $ title = ...?> Ora, ma esiste un modo più corretto?
jdavidbakr,

4
Le variabili devono essere passate dal controller, non dichiarate in linea nella vista. Se un modello globale necessita di una variabile, è possibile impostarlo in un provider di servizi stackoverflow.com/a/36780419/922522 . Se un modello specifico di pagina necessita di una variabile, utilizzare @yield e passarlo dalla vista figlio che ha un controller. laravel.com/docs/5.1/blade#template-inheritance
Justin

361

LARAVEL 5.5 E UP

La direttiva blade @php non accetta più tag in linea. Utilizza invece la forma completa della direttiva:

@php
$i = 1
@endphp

LARAVEL 5.2 E UP

Puoi semplicemente usare:

@php ($i = 1)

Oppure puoi usarlo in un'istruzione di blocco:

@php
$i = 1
@endphp

LARAVEL 5

Estendi la lama in questo modo:

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

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

Quindi esegui una delle seguenti operazioni:

Soluzione rapida: se sei pigro, inserisci il codice nella funzione boot () di AppServiceProvider.php.

Soluzione migliore: creare un proprio fornitore di servizi. Vedi https://stackoverflow.com/a/28641054/2169147 su come estendere il blade in Laravel 5. È un po 'più di lavoro in questo modo, ma un buon esercizio su come usare i provider :)

LARAVEL 4

Puoi semplicemente mettere il codice sopra nella parte inferiore di app / start / global.php (o in qualsiasi altro posto se ritieni che sia meglio).


Dopo le modifiche di cui sopra, è possibile utilizzare:

@define $i = 1

per definire una variabile.


5
Bello! Si noti che è possibile eseguire qualsiasi istruzione php con la propria implementazione. Lo rinominerei in soemething come @php. Molto utile ...
igaster

Verissimo, igastro. Puoi rinominare 'define' in 'php' se vuoi, ma questo apre la trappola all'utilizzo eccessivo di php nei tuoi template :)
Pim

1
Grazie @ C.delaFonteijne, se stai usando lo spazio dei nomi (e dovresti), il \ è davvero necessario. Ho aggiunto il \ nel codice sopra.
Pim

1
Nota che quasi la tua esatta implementazione è standard da Laravel 5.2 . Puoi usarlo @php(@i = 1)o usarlo in un'istruzione block (chiudi con @endphp)
Daan,

1
Non vedo come "@php" "@endphp" sia "più elegante" di "<? Php" "?>". Sono anche più pochi personaggi! È solo perché inizia con una "@" come le altre direttive Blade? Noi sviluppatori siamo un gruppo ossessivo-compulsivo! ;-)
OMA

116

Nel , puoi utilizzare la sintassi del commento del modello per definire / impostare le variabili.

La sintassi del commento è {{-- anything here is comment --}}ed è resa da motore come

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

quindi con un piccolo trucco possiamo usarlo per definire le variabili, per esempio

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

sarà reso da come <?php /* */$i=0;/* */ ?>imposta la variabile per noi. Senza cambiare alcuna riga di codice.


2
@ try-tobemyself +1 | Non è il metodo Best-Practices , ma perfetto per l'hacking rapido del codice in modelli come con stili incorporati per HTML.
Markus Hofmann,

121
Non consiglierei di fare questo hack come chiunque guardi questo codice dopo che ti odierà.
Giustino,

2
D'accordo con Justin, i tag di commento sono per commenti, per decommentare all'interno del commento e iniziare a fare qualcos'altro è chiedere problemi
Leon

27
Non è meglio del semplice php<?php $i=0; ?>
gyo del

3
Che senso ha fare questo invece di usare i tag php ?? Non è leggibile (sembra un commento), richiede una maggiore digitazione e potrebbe rompersi con un aggiornamento del sistema di analisi. Anche se ha un punto, non è la risposta a come definire una variabile in un modello di lama. Non sai cosa c'è che non va negli elettori, forse l'hanno trovato così "geniale"? meh ...
SuperDuck,

52

Esiste una semplice soluzione che non richiede la modifica di alcun codice e funziona anche in Laravel 4.

Basta usare un operatore di assegnazione ( =) nell'espressione passata a @ifun'istruzione, anziché (ad esempio) un operatore come ==.

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

Quindi puoi usarlo ovunque puoi usare qualsiasi altra variabile

{{ $variable }}

L'unico aspetto negativo è che il tuo incarico sembrerà un errore a qualcuno non consapevole che lo stai facendo come soluzione alternativa.


27

Lo renderai troppo complicato.

Usa semplicemente php

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

donesies.

(o https://github.com/alexdover/blade-set sembra anche abbastanza diretto)

Stiamo tutti un po '"hackerando" il sistema impostando variabili nelle viste, quindi perché rendere "hack" più complicato di quanto debba essere?

Testato in Laravel 4.

Un altro vantaggio è che l'evidenziazione della sintassi funziona correttamente (prima utilizzavo l'hacking dei commenti ed era orribile da leggere)


21

È possibile impostare le variabili nel motore di template della lama I seguenti modi:

1.
Variabile di impostazione del blocco PHP generale : <?php $hello = "Hello World!"; ?>
Uscita: {{$hello}}

2.
Variabile di impostazione del blocco PHP lama : @php $hello = "Hello World!"; @endphp
Uscita: {{$hello}}


19

Da Laravel 5.2.23, hai la direttiva @php Blade , che puoi usare in linea o come istruzione di blocco:

@php($old_section = "whatever")

o

@php
    $old_section = "whatever"
@endphp

15

È possibile impostare una variabile nel file di visualizzazione, ma verrà stampata esattamente come impostata. Comunque, c'è una soluzione alternativa. È possibile impostare la variabile all'interno di una sezione non utilizzata. Esempio:

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

Quindi {{ $yourVar }}stamperà Your valuedove vuoi, ma non ottieni l'output quando salvi la variabile.

MODIFICA: è richiesta la denominazione della sezione, altrimenti verrà generata un'eccezione.


Non funziona qualcos'altro deve essere incluso Proprietà non definita: Illuminate \ View \ Factory :: $ startSection (View: /home/vagrant/Code/dompetspy/resources/views/reviews/index.blade.php)
MaXi32

14

In Laravel 4:

Se desideri che la variabile sia accessibile in tutte le tue visualizzazioni, non solo nel tuo modello, View::shareè un ottimo metodo ( maggiori informazioni su questo blog ).

Basta aggiungere quanto segue in app / controller / BaseController.php

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

e ora $myvarsarà disponibile per tutte le visualizzazioni, incluso il modello.

L'ho usato per impostare URL di risorse specifici per l'ambiente per le mie immagini.


1
Questo è quello che stavo cercando: ottimo modo per evitare chiamate duplicate nel database!
clod986,

Questa non sembra essere un'opzione in Laravel 5?
Goddard,

@Goddard Puoi ancora. La sintassi è cambiata però: stackoverflow.com/a/36780419/922522
Justin

8

E all'improvviso non apparirà nulla. Dalla mia esperienza, se devi fare qualcosa del genere, prepara l'html nel metodo di un modello o esegui una riorganizzazione del codice in array o qualcosa del genere.

Non c'è mai solo 1 modo.

{{ $x = 1 ? '' : '' }}

11
Preparare l'HTML nel modello? Questa è la cosa più brutta che si possa immaginare.
dualità_

@dualità_ Stai dichiarando e modificando le variabili nella tua vista. Ho detto che probabilmente stai organizzando il tuo codice in modo errato. Architetto Lrn 2.
Michael J. Calkins,

3
Certo, Michael ... Quelle variabili non sono variabili come $users = ..., ma qualcosa lungo le linee $css_class = ..., quindi progettare rigorosamente variabili che non appartengono al modello o al controller, come sono determinate dal progettista.
dualità_

2
se hai bisogno di seguire questa strada, preferisco la soluzione più semplice ed elegante: {{''; $ x = 1}}
Daniel,


6

Ho intenzione di estendere la risposta data da @Pim.

Aggiungi questo al metodo di avvio di 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}; ?>";
});

In questo modo non esporre la capacità di scrivere alcuna espressione php.

Puoi usare questa direttiva come:

@set($var, 10)
@set($var2, 'some string')

5

In Laravel 5.1, 5.2 :

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

Potrebbe essere necessario condividere una parte di dati con tutte le viste visualizzate dall'applicazione. È possibile farlo utilizzando il metodo di condivisione della view factory. In genere, è necessario effettuare chiamate da condividere all'interno del metodo di avvio di un fornitore di servizi. Sei libero di aggiungerli ad AppServiceProvider o generare un fornitore di servizi separato per ospitarli.

Modifica file: /app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

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

    public function register()
    {
        // ...
    }
}


3

Per quanto riguarda il mio modo elegante è come il seguente

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

E fai eco alla tua $old_sectionvariabile.

{{ $old_section }}

3

Se hai PHP 7.0:

Il modo più semplice ed efficace è con l'assegnazione all'interno delle parentesi .

La regola è semplice: usi la tua variabile più di una volta? Quindi dichiaralo la prima volta che viene utilizzato tra parentesi, mantieni la calma e vai avanti.

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

E sì, lo so @forelse, questa è solo una demo.

Poiché le variabili sono ora dichiarate come e quando vengono utilizzate, non è necessario alcun accorgimento per i blade.


2

Non credo che tu possa - ma, di nuovo, questo tipo di logica dovrebbe probabilmente essere gestita nel tuo controller e passata alla vista già impostata.


6
Alcune variabili sono strettamente per le viste. $previous_group_name, $separator_printedecc.
dualità_

2
Se è solo per le viste, dovresti semplicemente passarlo alla vista dal controller. Se vuoi che sia disponibile per tutte le visualizzazioni, vedi la mia risposta sopra usando app/controllers/BaseController.php.
Giustino,

1
Sto usando più array per inviare tutti i miei $ dati alla vista
Hos Mercury,

2

Assegna una variabile al modello di lama, ecco le soluzioni

Possiamo usare il <?php ?>tag nella pagina blade

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

O

Possiamo usare il commento del blade con una sintassi speciale

{{--*/ $var = 'test' /*--}}
{{ $var }}

1

L'hacking dei commenti non è un modo molto leggibile per farlo. Inoltre gli editor lo coloreranno come un commento e qualcuno potrebbe non vederlo guardando il codice.

Prova qualcosa del genere:

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

Si compila in:

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

... e fai il compito e non fare eco.


1

È meglio esercitarsi a definire la variabile in Controller e quindi passare a visualizzare utilizzando compact()o il ->with()metodo.

Altrimenti #TLGreg ha dato la migliore risposta.


1

Esiste un'ottima estensione per le estensioni radic / blade Blade . Dopo averlo aggiunto puoi usare @set (nome_variabile, valore_variabile)

@set(var, 33)
{{$var}}

1

Stavo cercando un modo per assegnare un valore a una chiave e usarlo molte volte a mio avviso. In questo caso, è possibile utilizzare @section{"key", "value"}in primo luogo e quindi chiamare @yield{"key"}per generare il valore in altri punti nella vista o nel suo figlio.


0

Secondo me sarebbe meglio mantenere la logica nel controller e passarla alla vista per usarla. Questo può essere fatto in due modi usando il metodo 'View :: make'. Attualmente sto usando Laravel 3 ma sono abbastanza sicuro che sia lo stesso in Laravel 4.

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

o

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

Il metodo 'with' è concatenabile. Dovresti quindi utilizzare quanto sopra in questo modo:

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

Maggiori informazioni qui:

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

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


La logica di presentazione è meglio conservata nella vista. A volte, è necessario creare una variabile all'interno della vista. ad es. per formattare una data. $format='Y-m-d H:i:s';in questo modo è possibile riutilizzare quel formato all'interno della vista. Questo certamente non appartiene al controller. Detto questo, in risposta alla domanda ... Non c'è niente di sbagliato nei <?php ?>tag.
Sugo

0

Ho avuto una domanda simile e ho trovato quella che penso sia la soluzione corretta con View Composers

I compositori di viste consentono di impostare variabili ogni volta che viene chiamata una determinata vista e possono essere viste specifiche o interi modelli di vista. Ad ogni modo, so che non è una risposta diretta alla domanda (e 2 anni in ritardo) ma sembra una soluzione più aggraziata che impostare le variabili in una vista con blade.

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

0

laravel 5 puoi farlo facilmente. vedi sotto

{{--*/ @$variable_name = 'value'  /*--}}

0

È possibile estendere la lama utilizzando il metodo di estensione, come mostrato di seguito.

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

successivamente inizializzare le variabili come segue.

@var $var = "var"

-1

funziona in tutte le versioni di blade.

{{--*/  $optionsArray = ['A', 'B', 'C', 'D','E','F','G','H','J','K'] /*--}}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.