Examples

Create a dynamic sitemap.xml

You can create a dynamic sitemap who gives a list of every pages and blog posts.

At first you have to create a sitemap action into your AppBundle's controller :

<?php
namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use VFou\Cms\BlogBundle\Entity\Blog;
use VFou\CmsBundle\Entity\Page;
use VFou\CmsBundle\Entity\PageType;

class DefaultController extends Controller
{
    /**
     * @Route("/whatever/sitemap.xml", name="sitemap")
     */
    public function sitemapAction()
    {
        $em = $this->getDoctrine()->getManager();
        $pages = $em->getRepository(Page::class)->findAll();
        $blogs = $em->getRepository(Blog::class)->findAll();
        $blogType = $em->getRepository(PageType::class)->findOneByTitle("Blog");
        return new Response(
            $this->renderView("@App/Default/sitemap.xml.twig", 
                [
                    "pages"=>$pages, 
                    "blogs"=>$blogs, 
                    "blogType"=>$blogType
                ]
            ),
            200,
            [
                "Content-Type"=>"xml"
            ]
        );
    }
}

As you can see, we fetch from the database every pages and every blogs. We also keep the current "Blog" page type, we'll see soon why.

We renders a template located at src/AppBundle/Resources/views/default/sitemap.xml. Here's what are inside this template :

<?xml version="1.0" encoding="UTF-8" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    {% for page in pages %}
        {% if page.visible %}
            <url>
                <loc>{{ absolute_url(page.link|default("/")) }}</loc>
            </url>
            {% if page.type == blogType %}
                {% for blog in blogs %}
                    {% if blog.id == page.data %}
                        {% for post in blog.posts %}
                            {% if post.visible %}
                                <url>
                                    <loc>{{ absolute_url(page.link)~post.normalizedTitle }}</loc>
                                </url>
                            {% endif %}
                        {% endfor %}
                    {% endif %}
                {% endfor %}
            {% endif %}
        {% endif %}
    {% endfor %}
</urlset>

We look at every pages and check if they can appear in the file. If they can, we create an entry on the sitemap with the current url of the page. Additionally, if the current page is a blog (Note that we use the blogType variable we took earlier), we create as many entries than the current blog contains. We surely check before if the post is meant to be displayed.

Finally, you are free to add your new sitemap in your robots.txt file :

Sitemap: https://your-website.com/whatever/sitemap.xml

And that's all ! Your sitemap is now dynamically generated and search engines can now index your site more easily. As usual, if you have any questions or problems you can contact me on Twitter @VincentFoulon80