Jak ustawić zmienne w szablonie ostrza Laravela


248

Czytam dokumentację Laravel Blade i nie mogę wymyślić, jak przypisać zmienne w szablonie do późniejszego wykorzystania. Nie mogę tego zrobić, {{ $old_section = "whatever" }}ponieważ będzie to odzwierciedlać „cokolwiek” i nie chcę tego.

Rozumiem, że mogę <?php $old_section = "whatever"; ?>, ale to nie jest eleganckie.

Czy jest lepszy, elegancki sposób na zrobienie tego w szablonie Blade?


1
Sprawdź to ściągnięcie: github.com/laravel/laravel/pull/866
Spir

Jest to często przydatne do testowania, szczególnie jeśli pracujesz nad szablonem, ale ktoś inny pracuje nad częścią PHP. Uważaj, aby usunąć deklarację po zakończeniu testowania.
trysis

Co jest złego w zwykłym robieniu <?php $old_section = "whatever"; ?>. Uważam to za dość czytelne.
Jaime Hablutzel,

@JaimeHablutzel odpowiedź, moim zdaniem, brzmi: nie jest elegancka.
duality_

Odpowiedzi:


122

Odradza się robić to w widoku, więc nie ma dla niego znacznika ostrza. Jeśli chcesz to zrobić w widoku bloku, możesz po prostu otworzyć tag php podczas pisania lub zarejestrować nowy tag bloku. Tylko przykład:

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

9
Zmienne w widokach mają pewne zastosowania. To wygląda świetnie! Gdzie byłoby dobre miejsce na umieszczenie tego kodu?
duality_

1
Możesz umieścić go w aplikacji / start.php lub, jeśli będziesz mieć więcej takich rzeczy, umieść go w osobnym pliku i dołącz tam. Laravel jest bardzo luźny w ten sposób, możesz nawet rozrzedzić kontroler. Jedyne, co musisz zrobić, to rozciągnąć przed renderowaniem widoku.
TLGreg

19
Jaki jest powód dodania tego dodatkowego kodu tylko po to, aby używać go {?zamiast używać natywnego <??
Justin

1
Jeśli jest to odradzane, czy istnieje bardziej „właściwy” sposób na wykonanie następujących czynności? Mam witrynę, w której tytuł jest renderowany w głównym widoku aplikacji jako {{$ tytuł}}, który zawiera podsystem, który musi dołączyć numer strony do tytułu („Strona formularza wniosku {{$ page}}”) i Przesyłam $ page do widoku (który jest używany inaczej w widoku). Nie chcę budować tytułu w każdym wywołaniu kontrolera, chcę tylko wysłać widok numeru strony - na wszelki wypadek, gdy pewnego dnia chcę zmienić tytuł podstawowy. Używam teraz <? Php $ title = ...?>, Ale czy jest bardziej poprawny sposób?
jdavidbakr

4
Zmienne powinny być przekazywane z kontrolera, a nie deklarowane w twoim widoku. Jeśli szablon globalny potrzebuje zmiennej, możesz ustawić ją w usłudze stackoverflow.com/a/36780419/922522 . Jeśli szablon specyficzny dla strony potrzebuje zmiennej, użyj @yield i przekaż ją z widoku potomnego, który ma kontroler. laravel.com/docs/5.1/blade#template-inheritance
Justin

361

LARAVEL 5.5 I nowsze

Dyrektywa @php blade nie akceptuje już tagów wbudowanych. Zamiast tego użyj pełnej formy dyrektywy:

@php
$i = 1
@endphp

LARAVEL 5.2 I nowsze

Możesz po prostu użyć:

@php ($i = 1)

Lub możesz użyć go w instrukcji blokowej:

@php
$i = 1
@endphp

LARAVEL 5

Przedłuż ostrze w ten sposób:

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

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

Następnie wykonaj jedną z następujących czynności:

Szybkie rozwiązanie: jeśli jesteś leniwy, po prostu wstaw kod w funkcji boot () AppServiceProvider.php.

Lepsze rozwiązanie: stwórz własnego usługodawcę. Zobacz https://stackoverflow.com/a/28641054/2169147, jak przedłużyć ostrze w Laravel 5. To trochę więcej pracy w ten sposób, ale dobre ćwiczenie, jak korzystać z Dostawców :)

LARAVEL 4

Możesz po prostu umieścić powyższy kod na dole app / start / global.php (lub w dowolnym innym miejscu, jeśli uważasz, że jest to lepsze).


Po powyższych zmianach możesz użyć:

@define $i = 1

zdefiniować zmienną.


5
Miły! Pamiętaj, że możesz wykonać dowolną instrukcję php ze swoją implementacją. Zmieniłbym nazwę na coś takiego jak @php. Bardzo przydatny ...
igaster

Bardzo prawda, potwornie. Możesz zmienić nazwę „zdefiniować” na „php”, jeśli chcesz, ale to otwiera pułapkę na nadużywanie php w twoich szablonach :)
Pim

1
Dzięki @ C.delaFonteijne, jeśli używasz przestrzeni nazw (i powinieneś), \ jest naprawdę potrzebne. Dodałem \ w powyższym kodzie.
Pim

1
Pamiętaj, że prawie Twoja dokładna implementacja jest standardem od wersji Laravel 5.2 . Możesz użyć @php(@i = 1)lub użyć go w instrukcji blokowej (zamknij z @endphp)
Daan

1
Nie rozumiem, jak „@php” „@endphp” jest „bardziej elegancki” niż „<? Php” „?>”. To nawet kilka znaków dłużej! Czy to dlatego, że zaczyna się od „@”, jak inne dyrektywy Blade? My, programiści, jesteśmy grupą obsesyjno-kompulsywną! ;-)
OMA

116

W , możesz użyć składni komentarza szablonu, aby zdefiniować / ustawić zmienne.

Składnia komentarza jest {{-- anything here is comment --}}i jest renderowana przez silnik jak

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

więc przy pomocy małej sztuczki możemy na przykład użyć go do zdefiniowania zmiennych

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

będą renderowane przez a <?php /* */$i=0;/* */ ?>który ustawia zmienną dla nas. Bez zmiany jakiejkolwiek linii kodu.


2
@ próbuje-tobemyself +1 | Nie jest to najlepsza praktyka , ale idealna do szybkiego hakowania kodu w szablonach, takich jak wbudowane style HTML.
Markus Hofmann

121
Nie polecam robienia tego hacka, ponieważ każdy, kto patrzy na ten kod po tym, jak cię nienawidzi.
Justin

2
Zgadzam się z Justinem, tagi komentarzy służą do komentowania, aby odkomentować w komentarzu i zacząć robić coś innego, prosi o kłopoty
Leon

27
Nie jest to lepsze niż zwykły ol 'php<?php $i=0; ?>
gyo

3
Po co to robić zamiast używać tagów php? Nie można go odczytać (wygląda jak komentarz), wymaga więcej pisania i może zostać zepsuty przez aktualizację systemu analizowania. Nawet jeśli ma rację, nie jest to odpowiedź na pytanie, jak zdefiniować zmienną w szablonie bloku. Nie wiem, co jest nie tak z wyborcami, może uznali to za „dziwaczne”? meh ...
SuperDuck

52

Istnieje proste obejście, które nie wymaga zmiany żadnego kodu, i działa również w Laravel 4.

Wystarczy użyć operatora przypisania ( =) w wyrażeniu przekazanym do @ifinstrukcji, zamiast (na przykład) operatora takiego jak ==.

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

Następnie możesz użyć go w dowolnym miejscu i dowolnej innej zmiennej

{{ $variable }}

Jedynym minusem jest to, że twoje zadanie będzie wyglądać jak błąd dla osoby nieświadomej, że robisz to jako obejście.


27

Sprawi to, że będzie to zbyt skomplikowane.

Po prostu użyj zwykłego php

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

Donesies.

(lub https://github.com/alexdover/blade-set też wygląda dość prosto)

Wszyscy trochę „hakujemy” system, ustawiając zmienne w widokach, więc po co komplikować „hack” bardziej, niż trzeba?

Testowane w Laravel 4.

Kolejną zaletą jest to, że podświetlanie składni działa poprawnie (wcześniej używałem hackowania komentarzy i przeczytanie go było okropne)


21

Możesz ustawić zmienne w silniku szablonów ostrzy następujące sposoby:

1. Ogólny blok PHP
zmienna ustawienia : <?php $hello = "Hello World!"; ?>
Wyjście: {{$hello}}

2.
Zmienna ustawienia bloku ostrza PHP : @php $hello = "Hello World!"; @endphp
Wyjście: {{$hello}}


19

Od wersji Laravel 5.2.23 masz dyrektywę @php Blade , której możesz używać inline lub jako instrukcji blokowej:

@php($old_section = "whatever")

lub

@php
    $old_section = "whatever"
@endphp

15

Możesz ustawić zmienną w pliku widoku, ale zostanie ona wydrukowana tak jak ją ustawiłeś. W każdym razie istnieje obejście. Możesz ustawić zmienną w nieużywanej sekcji. Przykład:

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

Następnie {{ $yourVar }}wydrukujeYour value gdziekolwiek chcesz, ale nie otrzymasz danych wyjściowych po zapisaniu zmiennej.

EDYCJA: nazwa sekcji jest wymagana, w przeciwnym razie zostanie zgłoszony wyjątek.


Nie działa, należy dołączyć coś jeszcze Niezdefiniowana właściwość: Illuminate \ View \ Factory :: $ startSection (View: /home/vagrant/Code/dompetspy/resources/views/reviews/index.blade.php)
MaXi32

14

W Laravel 4:

Jeśli chcesz, aby zmienna była dostępna we wszystkich twoich widokach, nie tylko w szablonie, View::sharejest świetną metodą ( więcej informacji na tym blogu ).

Wystarczy dodać następujące elementy w app / controllers / BaseController.php

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

i teraz $myvarbędą dostępne dla wszystkich twoich widoków - w tym twojego szablonu.

Użyłem tego, aby ustawić adresy URL zasobów specyficzne dla środowiska dla moich obrazów.


1
Właśnie tego szukałem: świetny sposób na uniknięcie podwójnych połączeń w bazie danych!
clod986

To nie wydaje się być opcją w Laravel 5?
Goddard,

@Goddard Nadal możesz. Składnia uległa jednak zmianie: stackoverflow.com/a/36780419/922522
Justin

8

I nagle nic się nie pojawi. Z mojego doświadczenia wynika, że ​​jeśli musisz zrobić coś takiego, przygotuj HTML w metodzie modelu lub przeorganizuj swój kod w tablice lub coś takiego.

Nigdy nie ma tylko jednego sposobu.

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

11
Przygotować HTML w modelu? To najbrzydsza rzecz, jaką można sobie wyobrazić.
duality_

@ dualność Deklarujesz i zmieniasz zmienne w swoim widoku. Powiedziałem, że prawdopodobnie źle organizujesz swój kod. Architekt Lrn 2.
Michael J. Calkins

3
Jasne, Michael ... Te zmienne nie są zmienne takie jak $users = ..., ale coś wzdłuż linii $css_class = ..., więc ściśle projektuj zmienne, które nie należą do modelu ani kontrolera, ponieważ są określone przez projektanta.
duality_

2
jeśli chcesz iść tą drogą, wolę bardziej proste i eleganckie rozwiązanie: {{''; $ x = 1}}
Daniel


6

Przedłużę odpowiedź udzieloną przez @Pim.

Dodaj to do metody rozruchu swojego 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}; ?>";
});

W ten sposób nie ujawniasz możliwości napisania żadnego wyrażenia php.

Możesz użyć tej dyrektywy jak:

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

5

W Laravel 5.1, 5.2 :

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

Konieczne może być udostępnienie fragmentu danych wszystkim widokom renderowanym przez aplikację. Możesz to zrobić przy użyciu metody udostępniania fabryki widoków. Zazwyczaj należy nawiązywać połączenia w ramach metody rozruchu usługodawcy. Możesz dodać je do AppServiceProvider lub wygenerować osobnego dostawcę usług, aby je przechowywać.

Edytuj plik: /app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

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

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


3

Jeśli chodzi o mój elegancki sposób, wygląda to następująco

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

I po prostu powtórz swoją $old_sectionzmienną.

{{ $old_section }}

3

Jeśli masz PHP 7.0:

Najprostszym i najbardziej skutecznym sposobem jest przypisanie w nawiasach .

Zasada jest prosta: czy używasz swojej zmiennej więcej niż raz? Następnie zadeklaruj to przy pierwszym użyciu w nawiasach, zachowaj spokój i kontynuuj.

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

I tak, wiem o @forelsetym, to tylko wersja demonstracyjna.

Ponieważ twoje zmienne są teraz zadeklarowane jako i kiedy są używane, nie ma potrzeby żadnych obejść ostrza.


2

Nie sądzę, żebyś mógł - ale z drugiej strony tego rodzaju logika powinna być prawdopodobnie obsługiwana w twoim kontrolerze i przekazywana do już ustawionego widoku.


6
Niektóre zmienne dotyczą wyłącznie widoków. $previous_group_name, $separator_printeditp.
dwoistość_

2
Jeśli dotyczy to tylko widoków, powinieneś po prostu przekazać go do widoku z kontrolera. Jeśli chcesz, aby był dostępny dla wszystkich widoków, zobacz moją odpowiedź powyżej za pomocą app/controllers/BaseController.php.
Justin

1
Korzystam z wielu tablic, aby wysłać wszystkie moje dane $ do widoku
Hos Mercury

2

Przypisz zmienną do szablonu bloku, oto rozwiązania

Możemy użyć <?php ?>tagu na stronie bloku

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

LUB

Możemy użyć komentarza ostrza ze specjalną składnią

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

1

Hakowanie komentarzy nie jest zbyt czytelnym sposobem na zrobienie tego. Również redaktorzy pokolorują go jako komentarz i ktoś może go pominąć, przeglądając kod.

Wypróbuj coś takiego:

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

Skompiluje się w:

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

... i wykonuj zadanie i niczego nie odbijaj.


1

Lepiej poćwiczyć definiowanie zmiennej w sterowniku, a następnie przejść do widoku za pomocą compact()lub ->with()metody.

W przeciwnym razie #TLGreg udzielił najlepszej odpowiedzi.


1

Istnieje bardzo dobre rozszerzenie dla radic / rozszerzeń Blade . Po dodaniu możesz użyć @set (nazwa_zmiennej, wartość_zmiennej)

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

1

Szukałem sposobu, aby przypisać wartość do klucza i użyć go wiele razy według mnie. W tym przypadku możesz użyć @section{"key", "value"}w pierwszej kolejności, a następnie wywołać, @yield{"key"}aby wyświetlać wartość w innych miejscach w widoku lub jego potomku.


0

Moim zdaniem lepiej byłoby zachować logikę w kontrolerze i przekazać ją do użycia. Można to zrobić na dwa sposoby za pomocą metody „View :: make”. Obecnie używam Laravel 3, ale jestem prawie pewien, że jest tak samo w Laravel 4.

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

lub

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

Metoda „z” jest łańcuchowa. Następnie użyjesz powyższego w następujący sposób:

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

Więcej informacji tutaj:

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

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


Logikę prezentacji najlepiej zachować w polu widzenia. Czasami musisz utworzyć zmienną z widoku. np. aby sformatować datę. $format='Y-m-d H:i:s';w ten sposób możesz ponownie użyć tego formatu w widoku. To z pewnością nie należy do kontrolera. To powiedziawszy, w odpowiedzi na pytanie ... Nie ma nic złego w <?php ?>tagach.
Sos

0

Miałem podobne pytanie i znalazłem właściwe rozwiązanie w View Composers

Kompozytorzy widoków umożliwiają ustawienie zmiennych za każdym razem, gdy wywoływany jest określony widok, i mogą to być określone widoki lub całe szablony widoków. W każdym razie wiem, że nie jest to bezpośrednia odpowiedź na pytanie (i 2 lata za późno), ale wydaje się, że jest to bardziej wdzięczne rozwiązanie niż ustawianie zmiennych w widoku za pomocą ostrza.

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

0

laravel 5 możesz łatwo to zrobić. patrz poniżej

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

0

Możesz przedłużyć ostrze za pomocą metody przedłużenia, jak pokazano poniżej.

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

po tym zainicjuj zmienne w następujący sposób.

@var $var = "var"

-1

działa we wszystkich wersjach ostrza.

{{--*/  $optionsArray = ['A', 'B', 'C', 'D','E','F','G','H','J','K'] /*--}}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.