路由中的URL友好

时间:2017-01-16 11:55:31

标签: laravel laravel-5 laravel-5.2 laravel-routing

我在我的应用中创建了友好的网址,但它无法正常工作,应用程序正在向我提供与" - "相关的一些问题。 它给了我一个错误:

ErrorException in PostController.php line 60:
Trying to get property of non-object

我理想的网址是:

http://domain.com/CATEGORY-title-of-post-ID

我的路线是:

Route::get('{category}-{title}-{id}', 'PostController@show');

PostController show function:

public function show($category,$title,$id)
    {
        $post = Post::find($id);
        $user = Auth::user();

        $comments = Comment::where('post_id',$id)
                            ->where('approved',1)
                            ->get();




        return view('posts.show',compact('post','comments','user'));
    }

Blade View:

 <?php
     $title_seo = str_slug($feature->title, '-');
 ?>
 <a href="{{url($feature->categories[0]->internal_name."-".$title_seo."-".$feature->id)}}" rel="bookmark">
...</a>

2 个答案:

答案 0 :(得分:2)

有一个名为Eloquent-Sluggable的库,它会为每个帖子创建一个独特的slug并对其进行正确的URL编码。

要安装(取自文档):

composer require cviebrock/eloquent-sluggable:^4.1

然后,通过为服务提供商添加条目来更新config/app.php

'providers' => [
    // ...
    Cviebrock\EloquentSluggable\ServiceProvider::class,
];

最后,再次从命令行发布默认配置文件:

php artisan vendor:publish --provider="Cviebrock\EloquentSluggable\ServiceProvider"

要使用,请将Sluggable特征添加到您的模型中:

use Cviebrock\EloquentSluggable\Sluggable;

class Post extends Model
{
    use Sluggable;

    /**
 * Return the sluggable configuration array for this model.
 *
 * @return array
 */
public function sluggable()
{
    return [
        'slug' => [
            'source' => 'title'
            ]
        ];
    }

}

当您保存模型的实例时,库将自动创建一个slug并将其保存到模型表的新创建的slug列中。因此,要访问slug,您需要使用$model->slug

要获得所需的slug,而不是默认设置为title。您可以使用点符号传递source方法的sluggable属性数组字段名称,以访问相关模型的属性,如下所示:

public function sluggable()
{
    return [
        'slug' => [
            'source' => ['category.name','title','id']
            ]
        ];
    }

}

答案 1 :(得分:2)

为什么要手动归档“友好网址”?

你有route辅助函数,可以根据给定的参数为你构建一个URL。

Route::get('{category}-{title}-{id}', [
    'as => 'post.show', 
    'uses' => 'PostController@show'
]);

echo route('post.show', ['testing', 'title', 'id']); // http://domain.dev/testing-title-id

无论如何,这不是实施SEO友好URL的最佳方法。

在您的控制器中,您总是使用您的ID来查找帖子,这意味着类别和标题完全无用,无法确定需要向用户提供哪些资源。

您可以通过以下方式让您的生活更轻松:

Route::get('{id}-{slug}', [
    'as => 'post.show', 
    'uses' => 'PostController@show'
]);

echo route('post.show', ['id', 'slug']); // http://domain.dev/id-slug

在您的模型中,您将创建一个帮助函数,为您的帖子生成slug:

class Post
{
    [...]

    public function slug()
    {
        return str_slug("{$this->category}-{$this->title}");
    }
}

然后,在您的控制器中,您需要检查用于访问文章的slug是否正确,因为您不希望Google使用错误的slug索引帖子。您实质上强制URL以某种方式,并且您不会丢失索引点。

class PostController 
{
    [...]

    public function show($id, $slug)
    {
        $post = Post::findOrFail($id);
        $user = Auth::user();

        if ($post->slug() !== $slug) {
            return redirect()->route('posts.show', ['id' => 1, 'slug' => $post->slug()]);
        }

        $comments = Comment::where('post_id', $id)->where('approved', 1)->get();
        return view('posts.show', compact('post', 'comments', 'user'));
    }
}