Cómo establecer variables en una plantilla Laravel Blade


247

Estoy leyendo la documentación de Laravel Blade y no puedo entender cómo asignar variables dentro de una plantilla para su uso posterior. No puedo hacerlo {{ $old_section = "whatever" }}porque eso hará eco de "lo que sea" y no quiero eso.

Entiendo que puedo hacer <?php $old_section = "whatever"; ?>, pero eso no es elegante.

¿Hay una manera mejor y elegante de hacer eso en una plantilla Blade?


1
Verifique esta atracción: github.com/laravel/laravel/pull/866
Spir

Esto suele ser útil para las pruebas, especialmente si está trabajando en la plantilla pero alguien más trabaja en la parte de PHP. Solo tenga cuidado de eliminar la declaración cuando haya terminado las pruebas.
trysis

¿Qué tiene de malo simplemente hacer <?php $old_section = "whatever"; ?>? Me parece bastante legible.
Jaime Hablutzel el

@JaimeHablutzel la respuesta, en mi opinión, está en la pregunta: no es elegante.
dualidad_

Respuestas:


122

Se desaconseja hacerlo en una vista, por lo que no hay etiqueta de hoja para ello. Si desea hacer esto en su vista de Blade, puede abrir una etiqueta php tal como la escribió o registrar una nueva etiqueta Blade. Solo un ejemplo:

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

99
Las variables en las vistas tienen algunos usos. ¡Esto se ve genial! ¿Dónde sería un buen lugar para poner este código?
dualidad_

1
Puede ponerlo en su aplicación / start.php o si tiene más cosas como esta, póngalo en un archivo separado e inclúyalo allí. Laravel es muy suelto de esta manera, incluso podrías poner un controlador delgado. Lo único que tiene que hacer esto se extiende antes de que se visualice la vista.
TLGreg

19
¿Cuál es el razonamiento para agregar este código adicional solo para usar en {?lugar de solo usar el nativo <??
Justin

1
Si no se recomienda hacerlo, ¿hay alguna forma más "adecuada" de hacer lo siguiente? Tengo un sitio donde el título se representa en la vista principal de la aplicación como {{$ title}}, que contiene un subsistema que necesita agregar el número de página al título ("Página del formulario de solicitud {{$ page}}") y Estoy pasando $ page a la vista (que de lo contrario se usa dentro de la vista). No quiero construir el título en cada llamada al controlador, solo quiero enviarle a la vista el número de página, por si algún día quiero cambiar el título base. Estoy usando <? Php $ title = ...?> Ahora, pero ¿hay alguna forma más correcta?
jdavidbakr

44
Las variables deben pasarse desde el controlador, no declaradas en línea en su vista. Si una plantilla global necesita una variable, puede configurarla en un proveedor de servicios stackoverflow.com/a/36780419/922522 . Si una plantilla específica de página necesita una variable, use @yield y páselo desde la vista secundaria que tiene un controlador. laravel.com/docs/5.1/blade#template-inheritance
Justin

361

LARAVEL 5.5 Y ARRIBA

La directiva de la hoja @php ya no acepta etiquetas en línea. En su lugar, use la forma completa de la directiva:

@php
$i = 1
@endphp

LARAVEL 5.2 Y ARRIBA

Solo puedes usar:

@php ($i = 1)

O puede usarlo en una declaración de bloque:

@php
$i = 1
@endphp

LARAVEL 5

Extiende Blade así:

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

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

Luego, realice una de las siguientes acciones:

Solución rápida: si eres flojo, solo coloca el código en la función boot () de AppServiceProvider.php.

Mejor solución: cree un proveedor de servicios propio. Vea https://stackoverflow.com/a/28641054/2169147 sobre cómo extender la cuchilla en Laravel 5. Es un poco más de trabajo de esta manera, pero un buen ejercicio sobre cómo usar Proveedores :)

LARAVEL 4

Simplemente puede poner el código anterior en la parte inferior de app / start / global.php (o en cualquier otro lugar si cree que es mejor).


Después de los cambios anteriores, puede usar:

@define $i = 1

para definir una variable


55
¡Agradable! Tenga en cuenta que puede ejecutar cualquier declaración php con su implementación. Lo cambiaría a algo así como @php. Muy práctico ...
igaster

Muy cierto, igaster. Puede cambiar el nombre de 'definir' a 'php' si lo desea, pero eso abre el obstáculo al uso excesivo de php en sus plantillas :)
Pim

1
Gracias @ C.delaFonteijne, si está utilizando espacios de nombres (y debería hacerlo), la \ es realmente necesaria. He agregado la \ en el código anterior.
Pim

1
Tenga en cuenta que casi su implementación exacta es estándar desde Laravel 5.2 . Puede usarlo @php(@i = 1)o usarlo en una declaración de bloque (cerrar con @endphp)
Daan

1
No veo cómo "@php" "@endphp" es "más elegante" que "<? Php" "?>". ¡Incluso son algunos caracteres más largos! ¿Es solo porque comienza con una "@" como otras directivas de Blade? ¡Los desarrolladores somos un grupo obsesivo-compulsivo! ;-)
OMA

116

En , puede usar la sintaxis de comentarios de plantilla para definir / establecer variables.

La sintaxis del comentario es {{-- anything here is comment --}}y la representa motor como

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

así que con un pequeño truco podemos usarlo para definir variables, por ejemplo

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

será prestado por como lo <?php /* */$i=0;/* */ ?>que establece la variable para nosotros. Sin cambiar ninguna línea de código.


2
@ tratando de ser yo mismo +1 | No es la forma de las mejores prácticas , pero es perfecto para el pirateo rápido de código en plantillas como con estilos en línea para html.
Markus Hofmann

121
No recomendaría hacer este truco ya que cualquiera que vea este código después de que te odie.
Justin

2
De acuerdo con Justin, las etiquetas de comentarios son para comentarios, para descomentar dentro del comentario y comenzar a hacer otra cosa es pedir problemas
Leon

27
Esto no es mejor que el simple php<?php $i=0; ?>
gyo

3
¿Cuál es el punto de hacer esto en lugar de usar etiquetas php? No es legible (parece un comentario), requiere más tipeo y puede romperse con una actualización del sistema de análisis. Incluso si tiene un punto, no es la respuesta a cómo definir una variable en una plantilla de hoja. No sé qué les pasa a los votantes, ¿tal vez lo encontraron tan "geek"? meh ...
SuperDuck

52

Hay una solución simple que no requiere que cambie ningún código, y también funciona en Laravel 4.

Simplemente usa un operador de asignación ( =) en la expresión pasada a una @ifinstrucción, en lugar de (por ejemplo) un operador como ==.

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

Luego puede usarlo en cualquier lugar donde pueda usar cualquier otra variable

{{ $variable }}

El único inconveniente es que su tarea parecerá un error para alguien que no sabe que está haciendo esto como una solución alternativa.


27

Lo harás demasiado complicado.

Solo usa PHP simple

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

donesies

(o https://github.com/alexdover/blade-set también se ve bastante directo)

Todos estamos "pirateando" el sistema configurando variables en las vistas, entonces, ¿por qué hacer que el "pirateo" sea más complicado de lo que debe ser?

Probado en Laravel 4.

Otro beneficio es que el resaltado de sintaxis funciona correctamente (estaba usando un hack de comentarios antes y fue horrible de leer)


21

Puede establecer variables en el motor de plantillas de Blade de las siguientes maneras:

1.
Variable general de configuración de bloques PHP : <?php $hello = "Hello World!"; ?>
Salida: {{$hello}}

2.
Variable de configuración de bloques Blade PHP : @php $hello = "Hello World!"; @endphp
Salida: {{$hello}}


19

Desde Laravel 5.2.23, tiene la directiva @php Blade , que puede usar en línea o como instrucción de bloque:

@php($old_section = "whatever")

o

@php
    $old_section = "whatever"
@endphp

15

Puede establecer una variable en el archivo de vista, pero se imprimirá tal como la configuró. De todos modos, hay una solución alternativa. Puede establecer la variable dentro de una sección no utilizada. Ejemplo:

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

Luego {{ $yourVar }} imprimirá en Your valuecualquier lugar que desee, pero no obtendrá el resultado cuando guarde la variable.

EDITAR: se requiere nombrar la sección; de lo contrario, se lanzará una excepción.


No funciona. Se debe incluir algo más. Propiedad no definida: Illuminate \ View \ Factory :: $ startSection (View: /home/vagrant/Code/dompetspy/resources/views/reviews/index.blade.php)
MaXi32

14

En Laravel 4:

Si desea que la variable sea accesible en todas sus vistas, no solo en su plantilla, View::sharees un excelente método ( más información en este blog ).

Simplemente agregue lo siguiente en app / controllers / BaseController.php

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

y ahora $myvarestará disponible para todas sus vistas, incluida su plantilla.

Utilicé esto para establecer URL de activos específicos del entorno para mis imágenes.


1
Esto es lo que estaba buscando: ¡una excelente manera de evitar llamadas duplicadas en la base de datos!
clod986

¿Esto no parece ser una opción en Laravel 5?
Goddard

@ Goddard Todavía puedes. Sin embargo, la sintaxis ha cambiado: stackoverflow.com/a/36780419/922522
Justin

8

Y de repente nada aparecerá. Según mi experiencia, si tiene que hacer algo como esto, prepare el html en el método de un modelo o reorganice su código en matrices o algo así.

Nunca hay solo 1 camino.

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

11
¿Preparar el HTML en el modelo? Esa es la cosa más fea imaginable.
dualidad_

@duality_ Estás declarando y cambiando variables en tu vista. Dije que probablemente estés organizando mal tu código. Lrn 2 arquitecto.
Michael J. Calkins

3
Claro, Michael ... Esas variables no son variables tales como $users = ..., sino algo similar $css_class = ..., por lo que las variables de diseño estrictamente que no pertenecen al modelo o controlador, según lo determine el diseñador.
dualidad_

2
si necesita ir por esa ruta, prefiero la solución más simple y elegante: {{''; $ x = 1}}
Daniel

6

Voy a extender la respuesta dada por @Pim.

Agregue esto al método de arranque de su 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 esta manera no expones la capacidad de escribir ninguna expresión php.

Puede usar esta directiva como:

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


5

En Laravel 5.1, 5.2 :

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

Es posible que deba compartir un dato con todas las vistas que su aplicación representa. Puede hacerlo utilizando el método de compartir vista de fábrica. Por lo general, debe realizar llamadas para compartir dentro del método de arranque de un proveedor de servicios. Puede agregarlos al AppServiceProvider o generar un proveedor de servicios independiente para alojarlos.

Editar archivo: /app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

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

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


3

En cuanto a mi forma elegante es como la siguiente

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

Y solo repite tu $old_sectionvariable.

{{ $old_section }}

3

Si tienes PHP 7.0:

La forma más simple y efectiva es con la asignación entre paréntesis .

La regla es simple: ¿usa su variable más de una vez? Luego declare la primera vez que se usa entre paréntesis, mantenga la calma y continúe.

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

Y sí, lo sé @forelse, esto es solo una demostración.

Dado que sus variables ahora se declaran como y cuando se usan, no hay necesidad de ninguna solución alternativa.


2

No creo que pueda, pero, de nuevo, este tipo de lógica probablemente debería manejarse en su controlador y pasar a la vista ya configurada.


66
Algunas variables son estrictamente para vistas. $previous_group_name, $separator_printedetc.
duality_

2
Si es solo para vistas, solo debe pasarlo a la vista desde el controlador. Si desea que esté disponible para todas las vistas, consulte mi respuesta anterior usando app/controllers/BaseController.php.
Justin

1
Estoy usando múltiples matrices para enviar todos mis datos $ a la vista
Hos Mercury

2

Asignar variable a la plantilla de la cuchilla, aquí están las soluciones

Podemos usar la <?php ?>etiqueta en la página Blade

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

O

Podemos usar el comentario de la hoja con una sintaxis especial

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

1

Hackear comentarios no es una forma muy legible de hacerlo. También los editores lo colorearán como un comentario y alguien puede pasarlo por alto al mirar el código.

Intenta algo como esto:

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

Se compilará en:

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

... y hacer la tarea y no hacer eco de nada.


1

Es mejor practicar para definir la variable en el controlador y luego pasar a la vista usando compact()o ->with()método.

De lo contrario, #TLGreg dio la mejor respuesta.



1

Estaba buscando una manera de asignar un valor a una clave y usarla muchas veces desde mi punto de vista. Para este caso, puede usar @section{"key", "value"}en primer lugar y luego llamar @yield{"key"}para generar el valor en otros lugares en su vista o su hijo.


0

En mi opinión, sería mejor mantener la lógica en el controlador y pasarla a la vista para usar. Esto se puede hacer de dos maneras usando el método 'View :: make'. Actualmente estoy usando Laravel 3, pero estoy bastante seguro de que es igual en 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);
}

El método 'con' es encadenable. Luego usarías lo anterior así:

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

Más información aquí:

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

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


La lógica de presentación se mantiene mejor en la vista. A veces, debe crear una variable desde la vista. por ejemplo, formatear una fecha. $format='Y-m-d H:i:s';de esa manera puede reutilizar ese formato dentro de la vista. Esto ciertamente no pertenece al controlador. Dicho esto, en respuesta a la pregunta ... No hay nada malo con las <?php ?>etiquetas.
Salsa

0

Tuve una pregunta similar y encontré lo que creo que es la solución correcta con View Composers

Los Compositores de vista le permiten establecer variables cada vez que se llama a una vista determinada, y pueden ser vistas específicas o plantillas de vista completas. De todos modos, sé que no es una respuesta directa a la pregunta (y 2 años demasiado tarde), pero parece una solución más elegante que establecer variables dentro de una vista con blade.

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

0

Laravel 5 puede hacer esto fácilmente. vea abajo

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

0

Puede extender la cuchilla utilizando el método extendido como se muestra a continuación.

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

después de eso inicialice las variables de la siguiente manera.

@var $var = "var"

-1

Funciona en todas las versiones de blade.

{{--*/  $optionsArray = ['A', 'B', 'C', 'D','E','F','G','H','J','K'] /*--}}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.