简体   繁体   中英

How to use both ID and slug in Laravel 4 route URL? (resource/id/slug)

I would like to use both ID and slug in my articles route. So instead of /articles/ID I want /articles/ID/slug .

I don't actually need the slug variable for anything; it's just there to make the URL more readable and SEO, so I'll be using ID as identifier for retrieving the articles.

If the URL /articles/ID is entered I want to redirect to /articles/ID/slug . There has to be an exception for /articles/ID/edit since this opens the form for editing the article.

I've googled and looked this site, but I've only found examples of replacing ID with slug, not include both.

How can I achieve this? And can I use the URL class to get the full URL ( /articles/ID/slug ) for an article?

Current route config:

Route::resource('articles', 'ArticlesController');

So, here is what I ended up doing:

routes.php , created a custom route for show and edit . Used a resource for the rest:

Route::pattern('id', '[0-9]+');

Route::get('articles/{id}/{slug?}', ['as' => 'articles.show', 'uses' =>   'ArticlesController@show']);
Route::get('articles/edit/{id}', ['as' => 'articles.edit', 'uses' => 'ArticlesController@edit']);
Route::resource('articles', 'ArticlesController', ['except' => ['show', 'edit']]);

Controller, added a slug input parameter with a default value. Redirect the request if the slug is missing or incorrect, so it will redirect if the title is changed and return a HTTP 301 (permanently moved):

public function show($id, $slug = null)
{
    $post = Article::findOrFail($id);

    if ($slug != Str::slug($post->title))
        return Redirect::route('articles.show', array('id' => $post->id, 'slug' => Str::slug($post->title)), 301);

    return View::make('articles.show', [
        'article' => Article::with('writer')->findOrFail($id)
    ]);
}

View presenter, I originally had something in my model class. But moved it to a view presenter class on the basis of this answer: https://stackoverflow.com/a/25577174/3903565 , installed and used this: https://github.com/laracasts/Presenter

public function url()
{
    return URL::route('articles.show', array('id' => $this->id, 'slug' => Str::slug($this->title)));
}

public function stump()
{
    return Str::limit($this->content, 500);
}

View, get the url from the view presenter:

@foreach($articles as $article)
    <article>
        <h3>{{ HTML::link($article->present()->url, $article->title) }} <small>by {{ $article->writer->name }}</small></h3>
        <div class="body">
            <p>{{ $article->present()->stump }}</p>
            <p><a href="{{ $article->present()->url }}"><button type="button" class="btn btn-default btn-sm">Read more...</button></a></p>
        </div>
    </article>
@endforeach

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM