Como definir variáveis ​​em um modelo Laravel Blade

247

Estou lendo a documentação do Laravel Blade e não consigo descobrir como atribuir variáveis ​​dentro de um modelo para uso posterior. Não posso fazer {{ $old_section = "whatever" }}porque isso ecoará "tanto faz" e não quero isso.

Entendo que posso fazer <?php $old_section = "whatever"; ?>, mas isso não é elegante.

Existe uma maneira melhor e elegante de fazer isso em um modelo Blade?

dualidade_
fonte
1
Verifique essa atração: github.com/laravel/laravel/pull/866
Spir
Isso geralmente é útil para testes, especialmente se você estiver trabalhando no modelo, mas alguém trabalhar na parte do PHP. Apenas tome cuidado para remover a declaração ao concluir o teste.
trysis
O que há de errado em simplesmente fazer <?php $old_section = "whatever"; ?>. Acho bastante legível.
Jaime Hablutzel
@JaimeHablutzel a resposta, na minha opinião, está na pergunta: não é elegante.
Novidade

Respostas:

122

É desencorajado fazer isso em uma exibição, para que não exista uma etiqueta blade. Se você quiser fazer isso na visualização do blade, basta abrir uma tag php enquanto a escrevia ou registrar uma nova tag blade. Apenas um exemplo:

<?php
/**
 * <code>
 * {? $old_section = "whatever" ?}
 * </code>
 */
Blade::extend(function($value) {
    return preg_replace('/\{\?(.+)\?\}/', '<?php ${1} ?>', $value);
});
TLGreg
fonte
9
Variáveis ​​nas visualizações têm alguns usos. Isso parece ótimo! Onde seria um bom lugar para colocar esse código?
duality_
1
Você pode colocá-lo em seu aplicativo / start.php ou, se tiver mais coisas como essa, coloque-o em um arquivo separado e inclua-o lá. O Laravel é muito flexível dessa maneira, você pode até diluir um controlador. A única coisa que você precisa fazer é estender-se antes que a exibição seja renderizada.
TLGreg
19
Qual é o motivo para adicionar esse código extra apenas para usar em {?vez de apenas usar o nativo <??
Justin
1
Se for desencorajado, existe uma maneira mais "apropriada" de fazer o seguinte? Eu tenho um site em que o título é renderizado na visualização principal do aplicativo como {{$ title}}, que contém um subsistema que precisa anexar o número da página ao título ("Página do Formulário de Solicitação {{$ page}}" e Estou passando $ page para a visualização (que é usada de outra forma na visualização). Não quero criar o título em cada chamada do controlador, apenas desejo enviar à visualização o número da página - caso algum dia deseje alterar o título base. Estou usando <? Php $ title = ...?> Agora, mas existe uma maneira mais correta?
Jdavidbakr
4
Variáveis ​​devem ser passadas do controlador, não declaradas em linha na sua exibição. Se um modelo global precisar de uma variável, você poderá configurá-lo em um provedor de serviços stackoverflow.com/a/36780419/922522 . Se um modelo específico de página precisar de uma variável, use @yield e passe-o da exibição filho que possui um controlador. laravel.com/docs/5.1/blade#template-inheritance
Justin
361

LARAVEL 5.5 E ACIMA

A diretiva @php blade não aceita mais tags embutidas. Em vez disso, use o formulário completo da diretiva:

@php
$i = 1
@endphp

LARAVEL 5.2 E ACIMA

Você pode apenas usar:

@php ($i = 1)

Ou você pode usá-lo em uma instrução de bloco:

@php
$i = 1
@endphp

LARAVEL 5

Estenda o Blade assim:

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

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

Em seguida, siga um destes procedimentos:

Solução rápida: se você é preguiçoso, basta colocar o código na função boot () do AppServiceProvider.php.

Solução mais agradável: crie um provedor de serviços próprio. Consulte https://stackoverflow.com/a/28641054/2169147 sobre como estender o blade no Laravel 5. É um pouco mais trabalhoso dessa maneira, mas é um bom exercício de como usar provedores :)

LARAVEL 4

Você pode simplesmente colocar o código acima na parte inferior de app / start / global.php (ou qualquer outro lugar, se achar que é melhor).


Após as alterações acima, você pode usar:

@define $i = 1

para definir uma variável.

Pim
fonte
5
Agradável! Observe que você pode executar qualquer instrução php com sua implementação. Eu o renomearia para algo como @php. Muito útil ...
igaster
Muito verdade, igaster. Você pode renomear 'definir' para 'php' se você quiser, mas que abre a armadilha a mais-usando php em seus modelos :)
Pim
1
Obrigado @ C.delaFonteijne, se você estiver usando namespacing (e deveria), o \ é realmente necessário. Eu adicionei o \ no código acima.
Pim
1
Observe que quase sua implementação exata é padrão desde o Laravel 5.2 . Você pode usá @php(@i = 1)-lo ou usá-lo em uma instrução de bloco (próximo a @endphp)
Daan
1
Não vejo como "@php" "@endphp" é "mais elegante" que "<? Php" "?>". É ainda mais alguns caracteres! É apenas porque começa com um "@" como outras diretivas do Blade? Nós desenvolvedores somos um bando obsessivo-compulsivo! ;-)
OMA
116

No , você pode usar a sintaxe de comentário do modelo para definir / definir variáveis.

A sintaxe do comentário é {{-- anything here is comment --}} e é renderizada por motor como

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

então, com pouco truque, podemos usá-lo para definir variáveis, por exemplo

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

será processado por conforme <?php /* */$i=0;/* */ ?>define a variável para nós. Sem alterar nenhuma linha de código.

Tentando Tobemyself
fonte
2
@ tentando-se + 1 | Não é o caminho das práticas recomendadas , mas é perfeito para o hacking rápido de código em modelos, como nos estilos embutidos para html.
Markus Hofmann
121
Eu não recomendaria fazer esse hack, pois quem olha para esse código depois que você vai odiar você.
Justin
2
Concorde com Justin, as tags de comentários são para comentários, para descomentar dentro do comentário e começar a fazer outra coisa que está pedindo problemas #
Leon Leon
27
Isso não é melhor do que o simples ol 'php<?php $i=0; ?>
gyo
3
Qual é o objetivo de fazer isso em vez de usar tags php? Não é legível (parece um comentário), requer mais digitação e pode ser interrompido com uma atualização do sistema de análise. Mesmo que tenha um ponto, não é a resposta para definir uma variável em um modelo blade. Não sei o que há de errado com os eleitores, talvez eles achem isso tão "nerd"? meh ...
SuperDuck 24/16
52

Existe uma solução simples que não requer que você altere nenhum código, e funciona no Laravel 4 também.

Você apenas usa um operador de atribuição ( =) na expressão passada para uma @ifinstrução, em vez de (por exemplo) um operador como ==.

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

Então você pode usá-lo em qualquer lugar que você possa usar qualquer outra variável

{{ $variable }}

A única desvantagem é que sua tarefa parecerá um erro para alguém que não sabe que você está fazendo isso como uma solução alternativa.

BTMPL
fonte
27

Você está tornando isso muito complicado.

Basta usar php simples

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

donesies.

(ou https://github.com/alexdover/blade-set também parece bastante direto)

Estamos todos "invadindo" o sistema, definindo variáveis ​​em visualizações, então por que tornar o "hack" mais complicado do que precisa?

Testado no Laravel 4.

Outro benefício é que o destaque da sintaxe funciona corretamente (eu estava usando o hack de comentários antes e era horrível ler)

Sabrina Leggett
fonte
21

Você pode definir variáveis ​​no mecanismo de modelagem do blade das seguintes maneiras:

1.
Variável geral de configuração do bloco PHP : <?php $hello = "Hello World!"; ?>
Saída: {{$hello}}

2.
Variável de configuração do bloco PHP da lâmina : @php $hello = "Hello World!"; @endphp
Saída: {{$hello}}

Prince Ahmed
fonte
19

Desde o Laravel 5.2.23, você tem a diretiva @php Blade , que pode ser usada em linha ou como instrução de bloco:

@php($old_section = "whatever")

ou

@php
    $old_section = "whatever"
@endphp
Daan
fonte
15

Você pode definir uma variável no arquivo de exibição, mas ela será impressa exatamente como você a definiu. De qualquer forma, há uma solução alternativa. Você pode definir a variável dentro de uma seção não utilizada. Exemplo:

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

Em seguida {{ $yourVar }}, imprimirá Your valueonde quiser, mas você não obtém a saída quando salva a variável.

EDIT: é necessário nomear a seção, caso contrário uma exceção será lançada.

Vasile Goian
fonte
Não funciona. Outra coisa precisa ser incluída. Propriedade indefinida: Illuminate \ View \ Factory :: $ startSection (Exibir: /home/vagrant/Code/dompetspy/resources/views/reviews/index.blade.php)
MaXi32
14

No Laravel 4:

Se você deseja que a variável seja acessível em todas as suas visualizações, não apenas no seu modelo, View::shareé um ótimo método ( mais informações neste blog ).

Basta adicionar o seguinte em app / controllers / BaseController.php

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

e agora $myvar estará disponível para todas as suas visualizações, incluindo seu modelo.

Usei isso para definir URLs de ativos específicos do ambiente para minhas imagens.

Justin
fonte
1
Era isso que eu procurava: ótima maneira de evitar chamadas duplicadas no banco de dados!
Clod986
Isso não parece ser uma opção no Laravel 5?
Goddard
@ Goddard Você ainda pode. Sintaxe mudou entretanto: stackoverflow.com/a/36780419/922522
Justin
8

E de repente nada aparecerá. Pela minha experiência, se você tiver que fazer algo assim, prepare o html no método de um modelo ou faça alguma reorganização do seu código em matrizes ou algo assim.

Nunca existe apenas uma maneira.

{{ $x = 1 ? '' : '' }}
Michael J. Calkins
fonte
11
Prepare o HTML no modelo? Essa é a coisa mais feia que se possa imaginar.
duality_
@duality_ Você está declarando e alterando variáveis ​​na sua visualização. Eu disse que você provavelmente está organizando seu código errado. Arquiteto Lrn 2.
Michael J. Calkins
3
Claro, Michael ... Essas variáveis ​​não são variáveis ​​como $users = ..., mas algo $css_class = ...semelhante, projetando estritamente variáveis ​​que não pertencem ao modelo ou controlador, conforme são determinadas pelo designer.
283:
2
se você precisar seguir esse caminho, prefiro a solução mais simples e elegante: {{''; $ x = 1}}
Daniel
6

Vou estender a resposta dada pelo @Pim.

Adicione isso ao método de inicialização do seu 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}; ?>";
});

Dessa forma, você não expõe a capacidade de escrever qualquer expressão php.

Você pode usar esta diretiva como:

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

No Laravel 5.1, 5.2 :

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

Pode ser necessário compartilhar um dado com todas as visualizações renderizadas pelo seu aplicativo. Você pode fazer isso usando o método de compartilhamento da fábrica de exibição. Normalmente, você deve fazer chamadas para compartilhar no método de inicialização de um provedor de serviços. Você pode adicioná-los ao AppServiceProvider ou gerar um provedor de serviços separado para alojá-los.

Editar arquivo: /app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

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

    public function register()
    {
        // ...
    }
}
Justin
fonte
5

Você pode usar o pacote que publiquei: https://github.com/sineld/bladeset

Então você define facilmente sua variável:

@set('myVariable', $existing_variable)

// or

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

Quanto à minha maneira elegante é como o seguinte

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

E apenas ecoar sua $old_sectionvariável.

{{ $old_section }}
Set Kyar Wa Lar
fonte
3

Se você possui PHP 7.0:

A maneira mais simples e eficaz é com a atribuição entre colchetes .

A regra é simples: você usa sua variável mais de uma vez? Em seguida, declare-o na primeira vez em que for usado entre parênteses, mantenha a calma e continue.

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

E sim, eu sei @forelse, isso é apenas uma demonstração.

Como suas variáveis ​​agora são declaradas como e quando são usadas, não há necessidade de nenhuma solução alternativa para o blade.

Jonathan
fonte
2

Eu não acho que você pode - mas, novamente, esse tipo de lógica provavelmente deve ser tratado em seu controlador e passado para a exibição já definida.

Darren Craig
fonte
6
Algumas variáveis ​​são estritamente para visualizações. $previous_group_name, $separator_printed, Etc.
duality_
2
Se for apenas para visualizações, você deve apenas passá-lo para a visualização do controlador. Se você deseja disponibilizá-lo para todas as visualizações, veja minha resposta acima usando app/controllers/BaseController.php.
236 Justin Justin
1
Eu estou usando várias matrizes para enviar todos os dados My $ à vista
Hos Mercury
2

Atribuir variável ao modelo blade, Aqui estão as soluções

Podemos usar a <?php ?>tag na página blade

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

OU

Podemos usar o comentário blade com sintaxe especial

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

Hackear comentários não é uma maneira muito legível de fazer isso. Os editores também o colorirão como um comentário e alguém poderá sentir falta ao ler o código.

Tente algo como isto:

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

Ele será compilado em:

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

... e fazer a tarefa e não ecoar nada.

rotaercz
fonte
1

É melhor praticar para definir variável no Controller e depois passar para visualizar usando compact()ou ->with()método.

Caso contrário, o #TLGreg deu a melhor resposta.

Mandeep Gill
fonte
1

Existe uma extensão muito boa para o Blade radic / blade-extensions . Depois de adicioná-lo, você pode usar @set (variable_name, variable_value)

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

Eu estava procurando uma maneira de atribuir um valor a uma chave e usá-lo várias vezes na minha opinião. Nesse caso, você pode usar @section{"key", "value"}em primeiro lugar e depois chamar @yield{"key"}para gerar o valor em outros lugares em sua exibição ou em seu filho.

Hafez Divandari
fonte
0

Na minha opinião, seria melhor manter a lógica no controlador e passá-la para a visão de uso. Isso pode ser feito de duas maneiras, usando o método 'View :: make'. Atualmente, estou usando o Laravel 3, mas tenho certeza de que é da mesma forma no 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);
}

O método 'with' é encadeado. Você usaria o descrito acima da seguinte maneira:

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

Mais informações aqui:

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

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

Robert Brisita
fonte
A lógica da apresentação é melhor mantida na exibição. Às vezes, você precisa criar uma variável de dentro da visualização. por exemplo, para formatar uma data. $format='Y-m-d H:i:s';Dessa forma, você pode reutilizar esse formato na visualização. Isso certamente não pertence ao controlador. Dito isto, em resposta à pergunta ... Não há nada errado com as <?php ?>tags.
Gravy
0

Eu tive uma pergunta semelhante e encontrei o que eu acho ser a solução correta com o View Composers

Os compositores de exibição permitem definir variáveis ​​toda vez que uma determinada exibição é chamada e podem ser vistas específicas ou modelos de vista inteiros. De qualquer forma, eu sei que não é uma resposta direta à pergunta (e dois anos tarde demais), mas parece uma solução mais elegante do que definir variáveis ​​em uma exibição com o blade.

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

laravel 5 você pode fazer isso facilmente. ver abaixo

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

Você pode estender a lâmina usando o método de extensão, como mostrado abaixo.

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

depois disso, inicialize as variáveis ​​da seguinte maneira.

@var $var = "var"
Lakitha Dias
fonte
-1

funciona em todas as versões do blade.

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