prestaconcept / PrestaSitemapBundle

A symfony bundle that provides tools to build a rich application sitemap. The main goals are : simple, no databases, various namespace (eg. google image), respect constraints etc.
MIT License
355 stars 102 forks source link

Direct generate XML source as XML Response in browser. #269

Closed zhukovsergei closed 3 years ago

zhukovsergei commented 3 years ago

Hi! Thanks for the bundle! I have some question: Is it possible to use a bundle service for creation XML dump in memory? I just want to send for the user an XML response. I have imported Generator. But probably Dumper has only save into XML file.

 public function index(GeneratorInterface $generator)
    {
        $articles = [
            ['slug' => 'english-slug-1'],
            ['slug' => 'english-slug-2'],
            ['slug' => 'english-slug-3'],
        ];
        foreach ($articles as $article) {
            $url = new UrlConcrete('https://example.com/en/'.$article['slug']);
            $generator->addUrl($url, 'de');
        }

        dump($generator->generate());die;
    }

Actually $generator->generate() says null How can I generate the result as XML response? Thanks!

yann-eugone commented 3 years ago

Hi @zhukovsergei ! Thank you for using it :)

The Generator::generate method is a void method, so it will never return anything.

What you are trying to do is likely what we are doing when not using the dumper : render sitemap directly in a controller. Maybe you can have a look to that controller you may find this code a good way to start.

Please also note that I provided master branch links where Generator::generate was deprecated in favor of Generator::fetch. Feel free to switch branch for more accurate code on your version.

zhukovsergei commented 3 years ago

@yann-eugone Thanks for the answer! Can I somehow to add dynamic an urls? Thanks.

public function indexAction()
    {
        $sitemapindex = $this->generator->fetch('root');

        if (!$sitemapindex) {
            throw new NotFoundHttpException('Not found');
        }

        $response = new Response($sitemapindex->toXml());
        $response->headers->set('Content-Type', 'text/xml');
        $response->setPublic();
        $response->setClientTtl($this->ttl);

        return $response;
    }
yann-eugone commented 3 years ago

You copied/pasted the content of the SitemapController::indexAction which will generate the sitemap index : so you will never see URLs returned here ; only links to section sitemaps (which are those containing URLs).


I'm not sure to understand what you are trying to do. But I guess you can merge your 2 snippets :

    public function index()
    {
        $articles = [
            ['slug' => 'english-slug-1'],
            ['slug' => 'english-slug-2'],
            ['slug' => 'english-slug-3'],
        ];
        foreach ($articles as $article) {
            $url = new UrlConcrete('https://example.com/en/'.$article['slug']);
            $this->generator->addUrl($url, 'de');
        }

        $sitemap = $this->generator->fetch('de');
        if (!$sitemap) {
            throw new NotFoundHttpException('Not found');
        }

        $response = new Response($sitemap->toXml());
        $response->headers->set('Content-Type', 'text/xml');
        $response->setPublic();
        $response->setClientTtl($this->ttl);

        return $response;
    }
zhukovsergei commented 3 years ago

@yann-eugone I'm tried already this way xD But I'm getting sitemap of sitemaps.


<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd"
              xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <sitemap>
        <loc>http://localhost/sitemap.de.xml</loc>
        <lastmod>2021-01-08T11:44:20+01:00</lastmod>
    </sitemap>
    <sitemap>
        <loc>http://localhost/sitemap.en.xml</loc>
        <lastmod>2021-01-08T11:44:20+01:00</lastmod>
    </sitemap>
</sitemapindex>
yann-eugone commented 3 years ago

Yeah, that's what I was saying in my previous comment

You copied/pasted the content of the SitemapController::indexAction which will generate the sitemap index : so you will never see URLs returned here ; only links to section sitemaps (which are those containing URLs).

You should not fetch 'root', but the section you whish to render.

zhukovsergei commented 3 years ago

@yann-eugone aha! Now I got it, thanks a lot! It works!