Laravel: how to render only one section of a template?

前端 未结 4 1481
深忆病人
深忆病人 2020-12-05 00:50

I\'m trying to use pjax on my site, which means that for a full page request I render the whole template (this is normal behaviour), but on pjax requests I would like to ren

相关标签:
4条回答
  • 2020-12-05 01:27

    My best answer right now would be to state in your view that it must only extend the master template (layout) if the request is not being called via AJAX:

    @if(!Request::ajax())
        @extends('master.template')
    @endif
    

    Note, however, that this solution may not be best for your specific templates (I can only guess that). You'd need to make sure that each template/view only contains things that do not repeat, like side bars, etc. For example, if you have a content area that needs to be updated with pjax, then your view should only contain whatever should be changed.

    0 讨论(0)
  • 2020-12-05 01:28

    This is kind of an old question but I would like to throw down another solution.

    Lets say you have a view layout called main.blade.php and another view that extends main called page.blade.php

    main.blade.php

    <!DOCTYPE html>
    <html lang="en-GB">
    <head>
        <title>My Title</title>
    
        @section('head')
            <link rel="stylesheet" href="{{ URL::asset('css/style.css') }}">
        @show
    </head>
    <body>
    
        @yield('content')
    
        @section('footer')
            <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
            <script type="text/javascript" src="{{ URL::asset('js/main.js') }}"></script>
        @show
    </body>
    </html>
    

    page.blade.php

    @extends('main')
    
    @section('content')
        <div class="container">
            This is a rendered page
        </div>
    @stop
    

    Just a simple basic template to get things started. In your controller if you return a View::make('page') you will get the complete HTML but Laravel provides a way to return specific sections. Here is an example of how to display the content you want based on if its an ajax call or not from within your controller:

    my_controller.php

    function get_index() {
        $view = View::make('page');
    
        if(Request::ajax()) {
            $sections = $view->renderSections(); // returns an associative array of 'content', 'head' and 'footer'
    
            return $sections['content']; // this will only return whats in the content section
    
        }
    
        // just a regular request so return the whole view
    
        return $view;
    }
    

    Now when you make an ajax call to the page it will only return the content section rather than the entire HTML.

    0 讨论(0)
  • 2020-12-05 01:36

    Inside your controller's action, explicitly return the partial view you wanted to render:

    public function action_someajax()
    {
        ...
        return View::make('mypartial', $data);
    }
    

    This would render the partial instead of the controller's layout.

    0 讨论(0)
  • 2020-12-05 01:40

    Why wouldn't you just replace the actual content in the rendered page using a div or html element?

    I do this all the time with jQuery. I simply build my initial page and send content to my views that render sections in my master layout.

    Let's say I had a left navigation column and then an article in the right column. The user clicks a button to display the next article, so that's what I want to replace.

    First build the initial view from your controller

    public function index()
    {  
      $article = Article::first();
      Return View::make('homepage', compact('article'));
    }
    

    Now in your homepage view

    @extends('layouts.master')
    
    @section('leftNavigation')
         @include('homepageLeftNavigation')
    @stop
    
    @section('article')
       <div id="articleContent">
         @include('article') <!-- see below, you'll update this include with the js below -->
       </div>
    @stop
    
    @section('script')
    @parent
    {{-- <script> --}}
    //in JQuery I would do something like this
    $('a.nextArticle').click(function(){
       var next = $('.nextArticle').attr("id");
       var next = next + 1;
       $('#articleContent').load({{ URL::to('articles/' + next ) }};
    });
    @stop
    

    Assuming you're using a resourceful controller you could use your show() function, but if you just wanted a teaser on the homepage you could easily create a new function for that as well.

    In your show() or newFunctionWhateverYouCallIt() you can just get the article by id

    Article::find($id);
    

    Then send that off to a view to be rendered.

    return View::make('article');
    

    And finally the article view you called included the when you first built the page and again after updating via Jquery or pjax

         {{ $article->title }}
         {{ $article->body  }}
         {{ $article->date }}
         <a href="#" class="nextArticle" id="{{ $article->id }}">Next Article ></a>
    

    Please note I haven't tested this code so I'm sure there are a few mistakes, but you get the general idea of the logic for updating a single section of your page.

    0 讨论(0)
提交回复
热议问题