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

146

Я читаю Laravel Blade templating docs, и я не могу найти, как я могу назначать переменные внутри шаблона для использования позже шаблон. Я не могу сделать {{ $old_section = "whatever" }}, потому что это будет эхо "что угодно", и я не хочу этого.

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

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

  • 1
    Проверьте это притяжение: github.com/laravel/laravel/pull/866
  • 0
    Это часто полезно для тестирования, особенно если вы работаете над шаблоном, но кто-то еще работает над частью PHP. Просто будьте осторожны, чтобы удалить объявление, когда вы закончите тестирование.
Теги:
laravel-4

24 ответа

95
Лучший ответ

Не рекомендуется делать в представлении, поэтому для него нет метки. Если вы хотите сделать это в своем режиме просмотра лезвия, вы можете либо просто открыть тег php, как вы его написали, либо зарегистрировать новый тег. Пример:

<?php
/**
 * <code>
 * {? $old_section = "whatever" ?}
 * </code>
 */
Blade::extend(function($value) {
    return preg_replace('/\{\?(.+)\?\}/', '<?php ${1} ?>', $value);
});
  • 7
    Переменные в представлениях имеют некоторое применение. Это выглядит великолепно! Где было бы хорошее место, чтобы положить этот код?
  • 1
    Вы можете поместить его в свое приложение / start.php или, если у вас будет больше подобных вещей, поместить его в отдельный файл и включить в него. Laravel очень свободен в этом смысле, вы могли бы даже поставить тонкий контроллер. Единственное, что вам нужно сделать, это продлить до визуализации представления.
Показать ещё 6 комментариев
159

LARAVEL 5.2 И UP

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

@php ($i = 1)

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

@php
$i = 1
@endphp

LARAVEL 5

Расширьте Blade следующим образом:

/*
|--------------------------------------------------------------------------
| 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.

Решение Nicer: Создайте собственный поставщик услуг. См. https://stackoverflow.com/questions/18329541/where-to-place-bladeextend о том, как расширить лезвие в Laravel 5. Это немного больше работает таким образом, но хорошее упражнение по использованию Провайдеров:)

LARAVEL 4

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


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

@define $i = 1

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

  • 5
    Ницца! Обратите внимание, что вы можете выполнить любой оператор php с вашей реализацией. Я бы переименовал его в что-то вроде @php. Очень кстати...
  • 0
    Очень верно, игастер. Вы можете переименовать 'define' в 'php', если хотите, но это открывает ловушку для чрезмерного использования php в ваших шаблонах :)
Показать ещё 5 комментариев
113

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

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

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

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

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

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

  • 2
    @ пробовать себя +1 | Не лучший способ, но идеально подходит для быстрого взлома кода в шаблонах, например, с помощью встроенных стилей для HTML.
  • 113
    Я бы не советовал заниматься этим взломом, поскольку всем, кто смотрит на этот код после того, как вы будете ненавидеть вас
Показать ещё 5 комментариев
42

Существует одно обходное решение, которое не требует изменения какого-либо кода, и оно также работает в Laravel 4.

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

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

Затем вы можете использовать его везде, где вы можете использовать любую другую переменную

{{ $variable }}

Единственным недостатком является то, что ваше задание будет выглядеть как ошибка для кого-то, кто не знает, что вы делаете это как обходной путь.

13

Я сделаю это слишком сложным.

Просто используйте простой php

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

donesies.

(или https://github.com/alexdover/blade-set тоже выглядит довольно страшно)

Мы все вроде "взламываем" систему, задавая переменные в представлениях, поэтому зачем "взломать" сложнее, чем это должно быть?

Протестировано в Laravel 4.

Другим преимуществом является то, что подсветка синтаксиса работает должным образом (раньше я пользовался комментарием, и было ужасно читать)

12

В Laravel 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
    Это то, что я искал: отличный способ избежать дублирования вызовов в базе данных!
  • 0
    Кажется, это не вариант в Laravel 5?
Показать ещё 1 комментарий
9

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

@section
  {{ $yourVar = 'Your value' }}
@endsection

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

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

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

@php($old_section = "whatever")

или

@php
    $old_section = "whatever"
@endphp
  • 0
    Я не знаю, что это за лайнер, голосовал!
6

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

Существует не один способ.

{{ $x = 1 ? '' : '' }}
  • 11
    Подготовить HTML в модели? Это самая уродливая вещь, которую только можно представить.
  • 0
    @duality_ Вы объявляете и меняете переменные в своем представлении. Я сказал, что вы, вероятно, неправильно организовали свой код. Лрн 2 архитектор.
Показать ещё 2 комментария
5

Я продолжу ответ, полученный @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')
3

В Laravel 5.1, 5.2:

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

Возможно, вам понадобится поделиться куском данных с всеми представлениями, которые отображаются вашим приложением. Вы можете сделать это, используя метод представления factory. Как правило, вы должны размещать вызовы для совместного использования в рамках способа загрузки поставщика услуг. Вы можете добавлять их в AppServiceProvider или создавать отдельный поставщик услуг для их размещения.

Редактировать файл: /app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

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

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

Что касается моего элегантного способа, то это выглядит как

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

И просто откликните свою переменную $old_section.

{{ $old_section }}
2

Я не думаю, что вы можете - но опять же, такая логика, вероятно, должна быть обработана в вашем контроллере и передана в уже установленное представление.

  • 5
    Некоторые переменные предназначены исключительно для просмотра. $previous_group_name , $separator_printed и т. д.
  • 1
    Если это только для представлений, вы должны просто передать его представлению из контроллера. Если вы хотите, чтобы он был доступен для всех представлений, см. Мой ответ выше, используя app/controllers/BaseController.php .
Показать ещё 1 комментарий
1

Назначьте переменную шаблону лезвия. Ниже приведены решения

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

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

ИЛИ

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

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

Вы можете использовать пакет, который я опубликовал: https://github.com/sineld/bladeset

Тогда вы легко установите свою переменную:

@set('myVariable', $existing_variable)

// or

@set("myVariable", "Hello, World!")
1

Если у вас PHP 7.0:

Простой и эффективный способ заключается в назначении внутри скобок.

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

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

И да, я знаю о @forelse, это просто демо.

Так как ваши переменные теперь объявлены как и когда они используются, нет необходимости в каких-либо обходных методах.

1

laravel 5 вы можете легко это сделать. см. ниже

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

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

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

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

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

1

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

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

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

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

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

... и выполняйте назначение, а не эхо-сообщение.

0

работает во всех версиях клинка.

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

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

0

У меня был аналогичный вопрос и нашел, что я считаю правильным решением с Просмотр композиторов

View Composers позволяют вам устанавливать переменные каждый раз, когда вызывается определенное представление, и могут быть конкретными представлениями или целыми шаблонами. Во всяком случае, я знаю, что это не прямой ответ на вопрос (и еще 2 года слишком поздно), но это выглядит как более изящное решение, чем установка переменных в виде с лезвием.

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

  • 0
    Логика представления лучше всего держать в поле зрения. Иногда вам нужно создать переменную из представления. например, для форматирования даты. $format='Ymd H:i:s'; таким образом, вы можете повторно использовать этот формат в представлении. Это, конечно, не принадлежит контроллеру. Тем не менее, в ответ на вопрос ... В тегах <?php ?> Нет ничего плохого.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню