Laravel 4:在路线中使用灵活的布局

时间:2013-06-14 13:58:40

标签: php routes laravel laravel-4 template-engine

我有一个没有控制器的应用程序并阅读了controller layoutslaravel 4 documentation中的this other article too,但我不知道从哪里开始在路由(版本4)中实现它,如何我能这样做吗?

收到错误:InvalidArgumentException,找不到查看[master]。

应用程序/ routes.php文件

<?php
View::name('layouts.master', 'layout');
$layout = View::of('layout');
Route::get('users/create', array('as' => 'users.create', function() use($layout) {
  //@TODO: load view using 'layouts.master',
  //       desirable: append 'users.create' and 'users.menu' views to sidebar and content sections.
  //return View::make('users.create');
  return $layout->nest('content', 'master');
  }));
?>

应用程序/视图/布局/ master.blade.php

<html>
  <body>
    @section('sidebar')
      This is the master sidebar.
    @show

    <div class="container">
      @yield('content')
    </div>
  </body>
</html>

应用程序/视图/用户/ create.blade.php

{{ Form::open() }}

{{ Form::text('name') }}
{{ Form::submit('submit') }}

{{ Form::close() }}

应用程序/视图/用户/ menu.blade.php

<!-- This is appended to the master sidebar -->
<p><a href="users/create">Create user</a></p>

更新:我修改了示例代码以阐明我想要做的事情。查看app/routes.php及其评论

4 个答案:

答案 0 :(得分:4)

路由文件中的代码正在尝试将主布局嵌套在自身中,这实际上并不是您想要的。您收到错误是因为'master'会查找app/views/master.blade.php。通过将其更改为'layouts.master'可以很容易地解决这个问题,但我不想想会发生什么......

您遇到问题的根本原因是Blade模板中“让步”视图与路由嵌套之间的区别。嵌套路线时,您需要echo而不是使用@yield标记。

// File: app/routes.php

View::name('layouts.master', 'layout');
$layout = View::of('layout');

Route::get('users/create', array('as' => 'users.create', function() use ($layout)
{
    return $layout
            ->nest('content', 'users.create')
            ->nest('sidebar', 'users.menu');
}));


/*
|--------------------------------------------------------------------------
| View Composer
|--------------------------------------------------------------------------
|
| Code in this method will be applied to all views that use the master
| layout. We use that to our advantage by injecting an "empty" sidebar
| when none is set when returning the view. It will error otherwise.
|
*/

View::composer('layouts.master', function($view)
{
    if (!array_key_exists('sidebar', $view->getData()))
    {
        $view->with('sidebar', '');
    }
});


// File: app/views/layouts/master.blade.php

<html>
<body>
    @section('sidebar')
        This is the master sidebar
        {{ $sidebar }}
    @show

    <div class="container">
        {{ $content }}
    </div>
</body>
</html>

Laravel的View composers是一个强大的工具。如果您拥有共享相同模板的所有视图使用的任何数据(例如登录的用户信息),则可以使用编辑器在每次加载视图时保存注入数据。

答案 1 :(得分:0)

您也可以使用@parent标记来附加内容,假设您使用刀片进行模板化。例如。 (在视图中)

@section('sidebar')
    @parent
    <p>This is appended to the master sidebar.</p>
@stop

答案 2 :(得分:0)

如果您正在使用刀片,则无需使用嵌套视图。

应用程序/视图/用户/ create.blade.php

您需要扩展master.blade

@extends('layouts.master')
@section('content')
// form stuff here
@stop

现在,您需要做的就是致电create.blade

return View::make('users.create')

答案 3 :(得分:0)

将其作为使用控制器路由的可能解决方案抛出(而您可以在控制器内设置模板)。

应用程序/ routes.php文件

Route::controller('something', 'SomethingController');

应用程序/控制器/ SomethingController.php

class SomethingController extends BaseController {
  protected $layout = "templates.main"; // denotes views/templates/main.blade.php

  public function getIndex() { // the "landing" page for "/something" or "/something/index"
    $this->layout->content = View::make('something.index')->with("myVar", "Hello, world!"); // load in views/something/index.blade.php INTO main.blade.php
  }

  public function getTest() { // for "/something/test"
    $this->layout->content = View::make('something.index')->nest("widget", "something.widget", array("myVar" => "Hello, World!"));
  }
}

应用程序/视图/模板/ main.blade.php

@include('templates.partials.header')
@yield('something')
@yield('content')
@include('templates.partials.footer')

应用程序/视图/东西/ widget.blade.php

I'm a widget. {{ $myVar }}

应用程序/视图/东西/ index.blade.php

@section('something')
  I will go in the 'something' yield in main.blade.php
@stop

@section('content')
  I will go in the 'content' yield in main.blade.php.

  {{ $myVar }}

  {{ $widget }}
@stop

?>

现在,您可以测试http://myserver/somethinghttp://myserver/something/test以查看差异。注意:未经测试,但作为一个粗略的例子。