Как установить переменные в шаблоне лезвия Laravel


248

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

Я понимаю, что могу сделать <?php $old_section = "whatever"; ?>, но это не элегантно.

Есть ли лучший, элегантный способ сделать это в шаблоне Blade?


1
Проверьте это притяжение: github.com/laravel/laravel/pull/866
Spir

Это часто полезно для тестирования, особенно если вы работаете над шаблоном, но кто-то еще работает над частью PHP. Просто будьте осторожны, чтобы удалить объявление, когда вы закончите тестирование.
trysis

Что не так просто делать <?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}}») и Я передаю $ page в представление (которое иначе используется в представлении). Я не хочу создавать заголовок при каждом вызове контроллера, я просто хочу отправить просмотр номера страницы - на всякий случай, когда-нибудь я захочу изменить базовый заголовок. Я использую <? Php $ title = ...?> Сейчас, но есть ли более правильный способ?
jdavidbakr

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

361

LARAVEL 5.5 и выше

Директива @php blade больше не принимает встроенные теги. Вместо этого используйте полную форму директивы:

@php
$i = 1
@endphp

LARAVEL 5.2 и выше

Вы можете просто использовать:

@php ($i = 1)

Или вы можете использовать его в выражении блока:

@php
$i = 1
@endphp

LARAVEL 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

Вы можете просто поместить приведенный выше код внизу app / start / global.php (или в любое другое место, если считаете, что это лучше).


После вышеуказанных изменений вы можете использовать:

@define $i = 1

определить переменную.


5
Ницца! Обратите внимание, что вы можете выполнить любой оператор php с вашей реализацией. Я бы переименовал его в нечто вроде @php. Очень удобно ...
igaster

Очень верно, игастер. Вы можете переименовать 'define' в 'php', если хотите, но это открывает ловушку для чрезмерного использования php в ваших шаблонах :)
Pim

1
Спасибо @ C.delaFonteijne, если вы используете пространство имен (и вы должны это сделать), \ действительно необходим. Я добавил \ в коде выше.
Пим

1
Обратите внимание, что почти ваша точная реализация является стандартной, начиная с Laravel 5.2 . Вы можете использовать @php(@i = 1)или использовать его в выражении блока (закрыть с @endphp)
Daan

1
Я не понимаю, как "@php", "@endphp" "более элегантно", чем "<? Php" "?>". Это даже на несколько символов длиннее! Это просто потому, что начинается с "@", как и другие директивы Blade? Мы разработчики - какая-то навязчиво-компульсивная связка! ;-)
OMA

116

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

Синтаксис комментария есть {{-- anything here is comment --}}и он отображается двигатель как

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

поэтому с небольшой хитростью мы можем использовать его для определения переменных, например,

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

будет оказано как то, <?php /* */$i=0;/* */ ?>что устанавливает переменную для нас. Без изменения какой-либо строки кода.


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

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

2
Согласитесь с Джастином, теги комментариев предназначены для комментариев, чтобы раскомментировать комментарий и начать делать что-то еще, возникают проблемы
Леон

27
Это не лучше , чем обычная Ol»PHP<?php $i=0; ?>
GYO

3
Какой смысл делать это вместо использования тегов php ?? Он не читается (выглядит как комментарий), требует большего набора текста и может быть поврежден при обновлении системы синтаксического анализа. Даже если это имеет смысл, это не ответ на то, как определить переменную в шаблоне блейда. Не знаете, что не так с избирателями, возможно, они находят это настолько «отвратительным»?
Мех

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.
Переменная настройки блока Blade PHP : @php $hello = "Hello World!"; @endphp
Вывод: {{$hello}}


19

Начиная с Laravel 5.2.23, у вас есть директива @php Blade , которую вы можете использовать inline или как блок block:

@php($old_section = "whatever")

или

@php
    $old_section = "whatever"
@endphp

15

Вы можете установить переменную в файле представления, но она будет напечатана так же, как вы ее установили. Во всяком случае, есть обходной путь. Вы можете установить переменную внутри неиспользуемого раздела. Пример:

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

Затем {{ $yourVar }}напечатает в Your valueлюбом месте, где вы хотите, но вы не получите вывод при сохранении переменной.

РЕДАКТИРОВАТЬ: наименование раздела требуется, в противном случае будет выдано исключение.


Не работает, нужно включить что-то еще Неопределенное свойство: Illuminate \ View \ Factory :: $ startSection (View: /home/vagrant/Code/dompetspy/resources/views/reviews/index.blade.php)
MaXi32

14

В Ларавеле 4:

Если вы хотите, чтобы переменная была доступна во всех ваших представлениях, а не только в вашем шаблоне, View::shareэто отличный способ ( больше информации в этом блоге ).

Просто добавьте следующее в app / controllers / 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?
Годдард

@ Годдард Вы все еще можете. Синтаксис изменился, хотя: stackoverflow.com/a/36780419/922522
Джастин

8

И вдруг ничего не появится. По моему опыту, если вам нужно сделать что-то подобное, подготовьте HTML-код в методе модели или сделайте некоторую реорганизацию вашего кода в массивы или что-то в этом роде.

Там никогда не бывает только 1 способ.

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

11
Подготовить HTML в модели? Это самая уродливая вещь, которую только можно представить.
Duality_

@duality_ Вы объявляете и меняете переменные в своем представлении. Я сказал, что вы, вероятно, неправильно организовали свой код. Лрн 2 архитектор.
Майкл Дж. Калкинс

3
Конечно, Майкл ... Эти переменные не являются такими переменными, как $users = ..., а что-то похожее $css_class = ..., так что строго спроектируйте переменные, которые не принадлежат модели или контроллеру, как они определены дизайнером.
duality_

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

Возможно, вам придется поделиться частью данных со всеми представлениями , которые отображаются в вашем приложении. Вы можете сделать это, используя метод share фабрики представлений. Как правило, вы должны размещать вызовы для обмена в методе загрузки поставщика услуг. Вы можете добавить их в 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И т.д.
duality_

2
Если это только для представлений, вы должны просто передать его представлению из контроллера. Если вы хотите, чтобы он был доступен для всех просмотров, см. Мой ответ выше, используя app/controllers/BaseController.php.
Джастин

1
Я использую несколько массивов, чтобы отправить все свои $ data в представление
Hos Mercury

2

Присвойте переменную шаблону блейда. Вот решения

Мы можем использовать <?php ?>тег на странице лезвия

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

ИЛИ

Мы можем использовать комментарий лезвия со специальным синтаксисом

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

1

Взломать комментарии не очень читабельный способ сделать это. Редакторы также раскрасят его как комментарий, и кто-то может пропустить его при просмотре кода.

Попробуйте что-то вроде этого:

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

Он будет скомпилирован в:

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

... и делать задание и ничего не повторять.


1

Лучше потренироваться определить переменную в Controller, а затем перейти к просмотру с помощью метода compact()или ->with().

В противном случае #TLGreg дал лучший ответ.


1

Существует очень хорошее расширение для radic / blade-расширений Blade . После добавления вы можете использовать @set (имя_переменной, значение_переменной)

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

1

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


0

На мой взгляд, было бы лучше сохранить логику в контроллере и передать ее для использования. Это можно сделать одним из двух способов, используя метод View :: make. В настоящее время я использую 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

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

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.