Return XML From a Laravel Folio Route

Darrin Deal -

I absolutely love Laravel Folio. Having file based routing in my project has increased my productivity for sure. Folio was used to build the front facing portions of this site. Truly, I am a believer in this type of workflow. In building this site I ran into an issue.

The site needed a sitemap. That is an xml file and requires an update to the headers that are sent back to the browser via the response. I didn't want to use a package to generate the xml because it seems like unnecessary overhead. I know it was possible because I have a platform that generates a podcast feed using blade and adding the content type. How can we do that using Folio? Turns out to be very easy!

Base Blade

Let's say you have a blade file that looks like this 

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">  
    <url>        
	    <loc>{{ route('home') }}</loc>  
    </url> 
</urlset>

A simple sitemap xml that has the route to the home page.

Now what if I want to add the posts it might look like this.


<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">  
    <url>        
	    <loc>{{ route('home') }}</loc>  
    </url>
    @foreach($posts as $post)  
	    <url>  
	        <loc>{{ route('post', ['Post' => $post]) }}</loc>  
	        <lastmod>{{ $post->updated_at->format('Y-m-d') }}</lastmod>  
	    </url>
    @endforeach
</urlset>


Great! We have a viable sitemap. Let's say this file is at the root of our Folio directory and is called sitemap.blade.php. If we navigate to /sitemap we get this.

A jumbled mess...
Now that is not going to work. 

Introducing Render Hooks


Without adding anything else Folio will return the rendered output of your blade file. That's expected. To get a sitemap we need to modify the response that is returned to the browser. To accomplish that we need a render hook.

Folio provides a function that we can use called render. We can bring it in at the top of our blade file.

...
use Illuminate\View\View;  
use function Laravel\Folio\render;  
...

Then, to use the function we pass closure that accepts a View and any route parameters or bound modules. In the case of this tutorial we only have one line that we need so we can use an arrow function for our closure.

...
render(fn (View $view) => response($view)->header('Content-Type', 'text/xml'));
...

Passing in the closure as an arrow function we are returning a response with the view data and appending a header of Content-Type with a value of text/xml. Simple as that.

Now when we visit the sitemap we get what we expect. How great is that?

That's more like XML
Where to Go From Here?

How else do your think this could be used? The example in the docs shows how you can perform authorizations on your user in the render hook. Another use is to perform any actions before the view is rendered providing you an opportunity to pass data into the render process.

Let me know on X how you have used or how you will use these render hooks!