Як встановити змінні в шаблоні леза Laravel


248

Я читав Laravel Клинок документації , і я не можу зрозуміти, як призначити змінні в шаблоні для подальшого використання. Я не можу зробити це, {{ $old_section = "whatever" }}бо це лунатиме "що завгодно", і я цього не хочу.

Я розумію, що вмію <?php $old_section = "whatever"; ?>, але це не елегантно.

Чи є кращий, елегантний спосіб зробити це в шаблоні Blade?


1
Перевірте тягу: github.com/laravel/laravel/pull/866
Спір

Це часто корисно для тестування, особливо якщо ви працюєте над шаблоном, але хтось інший працює над частиною PHP. Будьте обережні, щоб видалити декларацію, коли закінчите тестування.
трис

Що не так у тому, щоб просто робити <?php $old_section = "whatever"; ?>. Я вважаю це досить читабельним.
Хайме Хаблуцель

@JaimeHablutzel відповідь, на мою думку, полягає у питанні: це не елегантно.
подвійність_

Відповіді:


122

Це не рекомендується робити в режимі перегляду, тому для нього не існує тегів леза. Якщо ви хочете зробити це у вашому перегляді лез, ви можете просто відкрити тег php, як ви його написали, або зареєструвати новий тег леза. Просто приклад:

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

9
Змінні в представленнях мають певне використання. Це виглядає чудово! Де було б добре розмістити цей код?
подвійність_

1
Ви можете помістити його у свою програму / start.php або якщо у вас буде більше таких речей, покладіть її в окремий файл і включіть туди. Laravel таким чином дуже пухкий, можна навіть поставити тонкий контролер. Єдине, що вам потрібно зробити, це розширюється до того, як подається перегляд.
TLGreg

19
Яке міркування для додавання цього додаткового коду просто використовувати {?замість того, щоб просто використовувати рідний <??
Джастін

1
Якщо це не рекомендується робити, чи є більш "правильний" спосіб зробити наступне? У мене є сайт, де заголовок відображається в головному вікні програми як {{$ title}}, який містить підсистему, якій потрібно додати номер сторінки до заголовка ("Сторінка форми заявки {{$ page}}") і Я передаю $ сторінку перегляду (який використовується інакше в межах перегляду). Я не хочу створювати заголовок у кожному виклику контролера, я просто хочу надіслати перегляд номер сторінки - про всяк випадок, коли я хочу змінити базовий заголовок. Я зараз використовую <? Php $ title = ...?>, Але чи є більш правильний спосіб?
jdavidbakr

4
Змінні повинні передаватися від контролера, а не оголошуватися вбудованими. Якщо глобальному шаблону потрібна змінна, ви можете встановити її в постачальника послуг stackoverflow.com/a/36780419/922522 . Якщо певному шаблону сторінки потрібна змінна, використовуйте @yield та передайте її з дочірнього виду, у якого є контролер. laravel.com/docs/5.1/blade#template-inheritance
Джастін

361

ЛАРАВЕЛ 5.5 і вище

Директива @php blade більше не приймає вбудовані теги. Натомість використовуйте повну форму директиви:

@php
$i = 1
@endphp

LARAVEL 5.2 І Вгору

Ви можете просто використовувати:

@php ($i = 1)

Або ви можете використовувати його в операторі блоку:

@php
$i = 1
@endphp

ЛАРАВЕЛ 5

Розтягніть лезо так:

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

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

Потім виконайте одну з наступних дій:

Швидке рішення: Якщо вам лінь, просто поставте код у функцію boot () AppServiceProvider.php.

Приємніше рішення: Створіть власного постачальника послуг. Дивіться https://stackoverflow.com/a/28641054/2169147 про те, як подовжити лезо в Laravel 5. Це трохи більше роботи, але хороша вправа щодо використання Провайдерів :)

ЛАРАВЕЛЬ 4

Ви можете просто поставити вищезазначений код у нижній частині програми / start / global.php (або будь-якого іншого місця, якщо вам здається, що це краще).


Після вищезазначених змін ви можете використовувати:

@define $i = 1

визначити змінну.


5
Приємно! Зверніть увагу, що ви можете виконати будь-яку заяву php під час своєї реалізації. Я б перейменував це на щось подібне до @php. Дуже зручно ...
ігастер

Дуже правдиво, ігастер. Ви можете перейменувати "визначити" на "php", якщо хочете, але це відкриє підводний камінь для надмірного використання php у ваших шаблонах :)
Пім

1
Дякуємо @ C.delaFonteijne, якщо ви користуєтесь простором імен (і вам слід), \ дійсно потрібен. Я додав \ у код вище.
Пім

1
Зверніть увагу, що майже Ваша точна реалізація є стандартною, оскільки Laravel 5.2 . Ви можете використовувати @php(@i = 1)або використовувати його в заяві блоку (закрити @endphp)
Даан

1
Я не бачу, наскільки "@php" "@endphp" є "більш елегантним", ніж "<? Php" "?>". Це навіть на кілька символів довше! Це лише тому, що він починається з "@", як і інші директиви Blade? Ми, розробники, - якийсь нав'язливо-нав'язливий зв'язок! ;-)
OMA

116

В , ви можете використовувати синтаксис коментаря до шаблону для визначення / встановлення змінних.

Синтаксис коментаря є, {{-- anything here is comment --}}і він надається двигун як

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

тому, маючи невелику хитрість, ми можемо використовувати його для визначення змінних, наприклад

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

буде надано як <?php /* */$i=0;/* */ ?>це встановлює нам змінну. Не змінюючи жодного рядка коду.


2
@ приміряє +1 +1 | Не найкращий спосіб, але ідеально підходить для швидкого злому коду в шаблонах, як, наприклад, стилі вбудованого для HTML.
Маркус Хофманн

121
Я б не рекомендував робити цей злом, як той, хто дивиться на цей код після того, як вас ненавиджу.
Джастін

2
Погодьтеся з Джастіном, теги коментарів - це коментарі, щоб коментувати коментар і почати робити щось інше, просить неприємностей
Леон

27
Це не краще, ніж звичайний ol 'php<?php $i=0; ?>
gyo

3
Який сенс робити це замість використання тегів php ?? Він не читабельний (схожий на коментар), вимагає більше вводити текст і може бути порушений при оновленні системи розбору. Навіть якщо у нього є точка, це не відповідь на те, як визначити змінну в шаблоні леза. Не знаєте, що трапилося з виборцями, можливо, вони вважають це таким "причудливим"? meh ...
SuperDuck

52

Існує просте вирішення, яке не вимагає від вас жодних змін, і він працює так само в Laravel 4.

Ви просто використовуєте оператор присвоєння ( =) у виразі, переданому до @ifоператора, замість (наприклад) такого оператора, як ==.

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

Тоді ви можете використовувати його будь-де, ви можете використовувати будь-яку іншу змінну

{{ $variable }}

Єдиним недоліком є те ваше завдання буде виглядати як помилка хто - то не знає , що ви робите це як обхідний шлях.


27

Я буду робити це занадто складно.

Просто використовуйте звичайний php

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

donesies.

(або https://github.com/alexdover/blade-set теж виглядає досить прямо)

Всі ми якось "хакуємо" систему, встановлюючи змінні в представленнях, так чому б "ускладнювати" складніше, ніж це потрібно?

Випробуваний у Laravel 4.

Ще одна перевага полягає в тому, що виділення синтаксису працює належним чином (я раніше використовував рубець коментарів, і це було жахливо читати)


21

Ви можете встановити змінні в двигуні шаблонів Blade наступними способами:

1. Загальна
змінна настройка блоку PHP : <?php $hello = "Hello World!"; ?>
Вихід: {{$hello}}

2.
Змінна настройка блоку PHP-блока : @php $hello = "Hello World!"; @endphp
Вихід: {{$hello}}


19

Починаючи з Laravel 5.2.23, у вас є директива @php Blade , яку ви можете використовувати вбудований або як блок заяви:

@php($old_section = "whatever")

або

@php
    $old_section = "whatever"
@endphp

15

Ви можете встановити змінну у файлі перегляду, але вона буде надрукована так само, як ви її встановили. У будь-якому випадку є рішення. Ви можете встановити змінну всередині невикористаного розділу. Приклад:

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

Потім {{ $yourVar }}буде надруковано в Your valueбудь-якому місці, де ви хочете, але ви не отримаєте вихід, коли збережете змінну.

EDIT: називання розділу потрібно, інакше буде викинуто виняток.


Не працює щось інше, потрібно включити Невизначене властивість: Illuminate \ View \ Factory :: $ startSection (Перегляд: /home/vagrant/Code/dompetspy/resources/views/reviews/index.blade.php)
MaXi32,

14

У Laravel 4:

Якщо ви хотіли, щоб змінна, доступна у всіх ваших переглядах, а не лише у вашому шаблоні, View::share- це чудовий метод ( детальніше про це в цьому блозі ).

Просто додайте наступне в додаток / контролери / BaseController.php

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

і тепер $myvarбуде доступний для всіх ваших переглядів - включаючи ваш шаблон.

Я використовував це для встановлення конкретних URL-адрес ресурсів для своїх зображень.


1
Це те, що я шукав: відмінний спосіб уникнути повторюваних дзвінків у базі даних!
clod986

Здається, це не є варіантом у Laravel 5?
Годдард

@Goddard Ви все ще можете. Синтаксис змінився, хоча: stackoverflow.com/a/36780419/922522
Джастін

8

І раптом нічого не з’явиться. З мого досвіду, якщо вам доведеться щось подібне, підготуйте html в методі моделі або зробіть якусь реорганізацію свого коду в масиви чи щось таке.

Ніколи не існує лише одного способу.

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

11
Підготувати HTML в моделі? Це найгірше, що можна уявити.
подвійність_

@duality_ Ви заявляєте та змінюєте змінні у вашому представленні. Я сказав, що ви, мабуть, неправильно впорядкували свій код. Лрн 2 архітектор.
Майкл Дж. Калкінс

3
Звичайно, Майкл ... Ці змінні - це не такі змінні, як $users = ..., а щось уздовж $css_class = ..., тому строго проектуйте змінні, які не належать до моделі чи контролера, як вони визначають дизайнер.
подвійність_

2
якщо вам потрібно пройти цей маршрут, я віддаю перевагу більш простому та елегантному рішенню: {{''; $ x = 1}}
Даніель


6

Я збираюся продовжити відповідь, надану @Pim.

Додайте це до методу завантаження вашого 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}; ?>";
});

Таким чином, ви не піддаєте можливості запису будь-якого виразу php.

Ви можете використовувати цю директиву, як:

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

5

У Laravel 5.1, 5.2 :

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

Можливо, вам доведеться поділитися частиною даних з усіма видами перегляду , які надаються вашою заявкою. Ви можете зробити це, використовуючи метод поділки фабрики перегляду. Як правило, вам слід здійснювати дзвінки для спільного використання в режимі завантаження постачальника послуг. Ви можете додати їх до AppServiceProvider або створити окремого постачальника послуг, щоб розмістити їх.

Редагувати файл: /app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

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

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


3

Що стосується мого елегантного способу, то наступного

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

І просто перегукуйтесь зі своєю $old_sectionзмінною.

{{ $old_section }}

3

Якщо у вас PHP 7.0:

Найпростіший і найефективніший спосіб - це призначення всередині дужок .

Правило просте: Ви використовуєте свою змінну більше одного разу? Потім заявіть про це вперше, коли він використовується в дужках, зберігайте спокій і продовжуйте.

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

І так, я знаю про @forelse, це просто демонстрація.

Оскільки ваші змінні тепер оголошуються як і коли вони використовуються, немає необхідності в жодних обхідних обрізах лез.


2

Я не думаю, що ви можете це зробити, але знову ж таки, таку логіку, мабуть, слід обробляти у вашому контролері та передавати у вже поданий вигляд.


6
Деякі змінні призначені виключно для переглядів. $previous_group_name, $separator_printedі т. д.
подвійність_

2
Якщо це лише перегляди, слід просто передати його перегляду від контролера. Якщо ви хочете, щоб вона була доступною для всіх переглядів, дивіться мою відповідь вище, використовуючи app/controllers/BaseController.php.
Джастін

1
Я використовую кілька масивів, щоб надіслати всі свої дані $ на вигляд
Hos Mercury

2

Призначте змінну шаблону леза, ось рішення

Ми можемо використовувати <?php ?>тег на сторінці леза

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

АБО

Ми можемо використовувати коментар леза із спеціальним синтаксисом

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

1

Злом коментарів - це не дуже читабельний спосіб зробити це. Також редактори забарвлять його як коментар, і хтось може пропустити його під час перегляду коду.

Спробуйте щось подібне:

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

Вона складеться в:

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

... і виконайте завдання, і нічого не лунайте.


1

Краще на практиці визначити змінну в Controller, а потім перейти до перегляду за допомогою compact()або ->with()методу.

Інакше #TLGreg дав найкращу відповідь.



1

Я шукав спосіб присвоїти значення ключу і використовувати його багато разів, на мій погляд. У цьому випадку ви можете використовувати @section{"key", "value"}в першу чергу, а потім зателефонувати, @yield{"key"}щоб вивести значення в інших місцях у вашому представленні даних або його дочірніх.


0

На мою думку, було б краще зберегти логіку в контролері і передати її перегляду для використання. Це можна зробити одним із двох способів, використовуючи метод «Переглянути :: зробити». Зараз я використовую Laravel 3, але я впевнений, що так само і в Laravel 4.

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

або

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

Метод "з" можливий. Потім ви використовуєте вищезгадане так:

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

Більше інформації тут:

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

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


Логіка презентації найкраще зберігатися в полі зору. Іноді вам потрібно створити змінну зсередини представлення даних. наприклад, для форматування дати. $format='Y-m-d H:i:s';таким чином ви можете повторно використовувати цей формат у представленні. Це, звичайно, не належить до контролера. Це сказало, відповідаючи на запитання ... З <?php ?>тегами немає нічого поганого .
Гравій

0

У мене було подібне питання, і я виявив, наскільки я вважаю, що це правильне рішення з View Composers

Композитори перегляду дозволяють встановлювати змінні щоразу, коли викликається певний вигляд, і це можуть бути конкретні представлення даних або цілі шаблони подання. У будь-якому випадку, я знаю, що це не пряма відповідь на питання (і на 2 роки занадто пізно), але це здається більш витонченим рішенням, ніж встановлення змінних в межах перегляду лезом.

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

0

laravel 5 ви легко можете це зробити. Дивись нижче

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

0

Ви можете розтягнути лезо, використовуючи метод розширення, як показано нижче ..

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

після цього ініціалізуйте змінні наступним чином.

@var $var = "var"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.