Search code examples
phplaravelvoyager

access database content on other pages in laravel


I am getting the error:

Trying to get property of non-object

I do var_dump($page) and it returns NULL.

I am trying to following exactly as I have already done in the project for posts, where I am able to do {{ $post->title }} but for pages I am getting this error and I don't understand why (I understand the meaning of the error but in context I don't know why it won't work for pages but does work for posts. The page does load if I don't try to pull any database content. I really don't know what I am missing.

PagesController:

namespace App\Http\Controllers;

use App\Page;
use Illuminate\Http\Request;

class PagesController extends Controller
{
    public function show($slug)
    {
        $page = Page::findBySlug($slug);
        return view('page.show', ['page' => $page]);
    }
}

Page Model

namespace App;

use Illuminate\Database\Eloquent\Model;

class Page extends Model
{
    public static function findBySlug($slug)
    {
        return static::where('slug', $slug)->first();
    }
}

views/page/show.blade.php

@extends('layouts.index')

@section('title', '-' . $page->title)
@section('header')
<?php //var_dump($page) ?>

<!-- Page Header -->
<header class="masthead" style="background-image: url('')">
    <div class="overlay"></div>
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-md-10 mx-auto">
                <div class="page-heading">
                    <span class="subheading">This is what I do.</span>
                </div>
            </div>
        </div>
    </div>
</header>

@stop

@section('content')

<!-- Main Content -->

    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-md-10 mx-auto">
                {!! $page->body !!}
            </div>
        </div>
    </div>


@stop

routes:

Route::get('/', 'TrainController@index');

Route::get('/post/{slug}', 'TrainController@show');
Route::get('{slug}', 'PagesController@show');


Route::group(['prefix' => 'admin'], function () {
    Voyager::routes();
});

views/layouts/index.blade.php:

<!DOCTYPE html>
<html lang="en">

  <head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>{{ setting('site.title') }}</title>

    <!-- Bootstrap core CSS -->
    <link href="/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom fonts for this template -->
    <link href="/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
    <link href='https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>

    <!-- Custom styles for this template -->
    <link href="/css/clean-blog.min.css" rel="stylesheet">
    <link href="/css/traintesting.css" rel="stylesheet">

  </head>

  <body>

    @include('partials.nav')
    @yield('header')


    <!-- Main Content -->
    <div class="container">
        @yield('content')
    </div>

    <hr>
    @include('partials.footer')
    <!-- Bootstrap core JavaScript -->
    <script src="/vendor/jquery/jquery.min.js"></script>
    <script src="/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

    <!-- Custom scripts for this template -->
    <script src="/js/clean-blog.min.js"></script>

  </body>

</html>

database: enter image description here enter image description here The code for posts which do work is:

Post Model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function author()
    {
        return $this->belongsTo(User::class,'author_id');
    }

    public static function findBySlug($slug)
    {
        return static::where('slug', $slug)->first();
    }
}

Controller:

namespace App\Http\Controllers;

use App\Post;
use Illuminate\Http\Request;

class TrainController extends Controller
{
    public function index()
    {
        $posts = Post::simplePaginate(2);
        return view('index', ['posts' => $posts]);
    }

    public function show($slug)
    {
        $post = Post::findBySlug($slug);
        return view('post.show',['post'=>$post]);
    }
}

views/partials/post.blade.php (used on index to click throught to post details)

<div class="post-preview">
    <a href="/post/{{ $post->slug }}">
        <h2 class="post-title">
            {{ $post->title }}
        </h2>
        <h3 class="post-subtitle">
            {{ $post->excerpt }}
        </h3>
    </a>
    <p class="post-meta">Posted by
        <a href="#">{{ $post->author->name }}</a>
        on {{ $post->created_at->format('l d F, Y') }}</p>
</div>
<hr>

views/post/show.blade.php:

@extends('layouts.index')

@section('title', '-' . $post->title)

@section('header')
<!-- Page Header -->
<header class="masthead" style="background-image: url('/storage/{{ $post->image }}')">

    <div class="overlay"></div>
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-md-10 mx-auto">
                <div class="post-heading">
                    <h1>{{ $post->title }}</h1>
                    <h2 class="subheading">{{ $post->sub_title }}</h2>
                    <span class="meta">Posted by
                <a href="#">{{ $post->author->name }}</a>
                {{ $post->created_at->format('l d F, Y') }}</span>
                </div>
            </div>
        </div>
    </div>
</header>
@stop

@section('content')


<!-- Post Content -->
<article>
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-md-10 mx-auto">
              {!! $post->body !!}
            </div>
        </div>
    </div>
</article>

<hr>


@stop

Solution

  • The error is self-explanatory, this means there is no record of this slug in DB and the query return the null. You add the condition if the record is null. Like below

    if(isset($page) and count($page)>0) {
      echo $page->title 
    } 
    
    or
    
    if(isset($page->title) and $page->title!='') {
      echo $page->title 
    }