Як встановити змінні в шаблоні леза 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.