skip to Main Content

My category url contains both id and slug like https://myapp.com/category/56-category-name (id field = 56 and slug field = category-name in the DB), when updating category name the slug field in DB is updated but the id still the same.
I would like to display my category whatever the slug provided that the id is correct and of course display the correct url. In this case SEO still correct i think.

Here my show method :

/**
 * @Route("/category/{id}-{slug}", name="category_show", requirements={"id"="d+"})
 */
public function show(CategoryRepository $categoryRepository, $slug, $id): Response
{

    $category = $categoryRepository->find($id);
    if($category->getSlug() !== $slug) {
        return $this->redirectToRoute('category_show', [
            'id' => $id,
            'slug' => $category->getSlug()
        ]);
    }
    return $this->render('category/show.html.twig', [
        'category' => $category
    ]);
}

It works if the given id exists in DB, othewise i got an error Call to a member function getSlug() on null. I can throw a NotFoundException, but i think this method use many times queries.

So please help me doing these properly with more flexibility and performance.
In case I would like to display the category in the post url as well like https://myapp.com/56-category-name/23-post-title how to go about it ??

Thanks in advance

2

Answers


  1. Chosen as BEST ANSWER

    here is what i found good for my app :

    in my CategoryController.php i create, the show method :

    /**
     * @Route("/{id}-{slug}", name="category_show", requirements={"id"="d+"})
     */
    public function show(CategoryRepository $categoryRepository, $slug = null, $id): Response
    {
    
        $category = $categoryRepository->find($id);
        
        if (!$category) {
            throw new NotFoundHttpException();
        }
    
        if($category->getSlug() !== $slug) {
            return $this->redirectToRoute('category_show', [
                'id' => $id,
                'slug' => $category->getSlug()
            ]);
        }
        return $this->render('category/show.html.twig', [
            'category' => $category
        ]);
    }
    

    in my index template to display the category_show link :

    <a href="{{ path('category_show', {'slug': category.slug, 'id': category.id}) }}">show</a>
    

    in my ArticleController.php i create, the show method :

    /**
     * @Route("/{category}/{id}-{slug}", name="article_show", requirements={"id"="d+"})
     */
    public function show(ArticleRepository $articleRepository, $slug = null, $id, $category = null): Response
    {
        $article = $articleRepository->find($id);
        
        if (!$article) {
            throw new NotFoundHttpException();
        }
        
        $cat = $article->getCategory()->getId() . '-' . $article->getCategory()->getSlug();
    
        if($article->getSlug() !== $slug || $cat !== $category) {
            return $this->redirectToRoute('article_show', [
                'id' => $id,
                'slug' => $article->getSlug(),
                'category' => $cat
            ]);
        }
        return $this->render('article/show.html.twig', [
            'article' => $article,
        ]);
    }
    

    in my index template to display the article_show link :

    <a href="{{ path('article_show', {'category': article.category.id ~ '-' ~ article.category.slug, 'slug': article.slug, 'id': article.id}) }}">show</a>
    

    For me that solves my problem. But still, if we can improve the process, I'm a buyer.

    Thanks


  2. Use findOneBy() and check if the result is null

    /**
     * @Route("/category/{id}-{slug}", name="category_show", requirements={"id"="d+"})
     * @Route("/{id}-{slug}/{idArticle}-{postSlug}", name="article_show", requirements={"idArticle"="d+"})
     */
    public function show(CategoryRepository $categoryRepository, $slug, $id, $idArticle = false, $postSlug = false ): Response
    {
    
        $category = $categoryRepository->findOneBy(['id'=>$id]);
        if(is_null($category)){
          throw new NotFoundHttpException(); //404, nothing found
        }else{
          //Category found.
          if($idArticle){ //  https://myapp.com/56-category-name/23-post-title
             //Article route, put your logic here 
          }else{ //https://myapp.com/category/56-category-name 
            // Category route, logic here
            if($category->getSlug() !== $slug) {
               return $this->redirectToRoute('category_show', [
                  'id' => $id,
                  'slug' => $category->getSlug()
               ]);
            }
            return $this->render('category/show.html.twig', [
              'category' => $category
            ]);
          }
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search