Comment utiliser ID et slug dans L'URL de route de Laravel 4? (ressource / id/slug)

je voudrais utiliser à la fois ID et slug dans mes articles route. Ainsi, au lieu de /articles/ID je veux /articles/ID/slug.

Je n'ai pas vraiment besoin de la variable slug pour quoi que ce soit; elle est juste là pour rendre L'URL plus lisible et SEO, donc je vais utiliser ID comme Identificateur pour récupérer les articles.

si L'URL /articles/ID est entré je veux rediriger vers /articles/ID/slug. Il doit y avoir une exception pour /articles/ID/edit puisque ceci ouvre la forme pour éditer le article.

j'ai cherché sur Google et j'ai regardé ce site, mais je n'ai trouvé que des exemples de remplacement D'ID par slug, pas les deux.

Comment puis-je y parvenir? Et puis-je utiliser le URL classe pour obtenir l'URL complète (/articles/ID/slug) pour un article?

itinéraire Actuel config:

Route::resource('articles', 'ArticlesController');
9
demandé sur Thomas Jensen 2014-08-29 16:32:52

1 réponses

Donc, voici ce que j'ai fait:

routes.php, créé une route personnalisée pour show et edit. Utilisé une ressource pour le reste:

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']]);

Contrôleur, a ajouté un slug paramètre d'entrée avec une valeur par défaut. Rediriger la requête si la balle est manquante ou incorrecte, elle redirigera donc si le titre est modifié et retournera un HTTP 301 (déplacé de façon permanente):

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)
    ]);
}

voir présentateur, j'avais à l'origine quelque chose dans ma classe de model. Mais déplacé dans un vue présentateur de la classe sur la base de cette réponse: https://stackoverflow.com/a/25577174/3903565, installé et utilisé ceci: 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);
}

Vue d'obtenir l'url de la vue présentateur:

@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
10
répondu Thomas Jensen 2017-05-23 12:17:26