generate dynamic sitemaps in a laravel project without using composer
Asked Answered
C

3

5

I want to generate Dynamic sitemap for my laravel project. I had already searched in so many sites for an answer. some of them describes it using composer. I didn't get how to do that. and in some other sites they wrote codes to get urls from db in loops. In my project db I didn't saved any urls. my project is a site for doctor and patients. so is there any one knows how to write php / laravel codes for dynamic sitemap generation.?

Edit

I'm a newbie to laravel so i'm just unfamiliar with this composer. can anyone please tell me if i download the laravel-sitemap-master.zip from github where i can extract it and saves in my project directory? it will be so much helpful if anyone please answer this.

Cappuccino answered 13/11, 2014 at 5:39 Comment(1)
this tutorial is good for this purpose dynamic sitemap laravel-news.com/laravel-sitemapCabriolet
C
19

Add this line to your routes.php

Route::get('/sitemap', function()
{
   return Response::view('sitemap')->header('Content-Type', 'application/xml');
});

Create new file app\Http\Middleware\sitemap.php

<?php namespace App\Http\Middleware;

use Closure;
use Carbon\Carbon;
use Illuminate\Contracts\Auth\Guard;

class sitemap {

    /**
     * The Guard implementation.
     *
     * @var Guard
     */
    protected $auth;

    public function __construct(Guard $auth)
    {
        $this->auth = $auth;
    }


    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure                 $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ( !$request->is("sitemap") && $request->fullUrl() != '' && $this->auth->guest() )
        {
            $aSiteMap = \Cache::get('sitemap', []);
            $changefreq = 'always';
            if ( !empty( $aSiteMap[$request->fullUrl()]['added'] ) ) {
                $aDateDiff = Carbon::createFromTimestamp( $aSiteMap[$request->fullUrl()]['added'] )->diff( Carbon::now() );
                if ( $aDateDiff->y > 0 ) {
                    $changefreq = 'yearly';
                } else if ( $aDateDiff->m > 0) {
                    $changefreq = 'monthly';
                } else if ( $aDateDiff->d > 6 ) {
                    $changefreq = 'weekly';
                } else if ( $aDateDiff->d > 0 && $aDateDiff->d < 7 ) {
                    $changefreq = 'daily';
                } else if ( $aDateDiff->h > 0 ) {
                    $changefreq = 'hourly';
                } else {
                    $changefreq = 'always';
                }
            }
            $aSiteMap[$request->fullUrl()] = [
                'added' => time(),
                'lastmod' => Carbon::now()->toIso8601String(),
                'priority' => 1 - substr_count($request->getPathInfo(), '/') / 10,
                'changefreq' => $changefreq
            ];
            \Cache::put('sitemap', $aSiteMap, 2880);
        }
        return $next($request);
    }
}

And create new view file resources\views\sitemap.blade.php

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
        xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
    @foreach( Cache::get('sitemap') as $url => $params )
    <url>
        <loc>{{$url}}</loc>
        <lastmod>{{$params['lastmod']}}</lastmod>
        <changefreq>{{$params['changefreq']}}</changefreq>
        <priority>{{$params['priority']}}</priority>
    </url>
    @endforeach
</urlset>

Add an entry to protected $middleware array in the file app\Http\Kernel.php

'sitemap' => 'App\Http\Middleware\sitemap'
Cloraclorinda answered 13/11, 2014 at 5:39 Comment(11)
This is vor laravel 5. This will generate site map by visiting pages.Cloraclorinda
I don't know why your answer not have any rate. +1Ready
where does he goes trough every link in the web? this looks like he gets something from cacheGwendagwendolen
No matter who goes trough links. Even you or bot or any other visitor. All visited links are cached and then from cache sitemap is generated.Cloraclorinda
Won't this also include pages that don't exist (404 pages), but have been visited?Acetometer
probably you should check the headers, but in worst scenario only one 404 page will be indexed. 404 page is still valid page - so why it should not to be in sitemap?Cloraclorinda
I don't like and recommend this way, because:Siftings
just because? or what?Cloraclorinda
@Cloraclorinda I want to exclude a few paths. How can I do that? Also, this adds every link, even the personalized links of users to cache. I want it to see only the pages which can be visited as guest.Malamut
Thanks FDisk. I did some changes to improve the middleware. gist.github.com/johnroyer/745ac3b0a88b2a43d8dac42427f55aa9Phalanstery
@vish4071: there is another solution. but I thinks it is too complicated. github.com/spatie/laravel-sitemapPhalanstery
P
7

Suppose you want your website's sitemap.xml file to include links to all doctors and patients you have in the database, you can do so like this:

in routes.php file..

Route::get("sitemap.xml", array(
    "as"   => "sitemap",
    "uses" => "HomeController@sitemap", // or any other controller you want to use
));

in HomeController.php file (if you decided to use HomeController)..

public function sitemap()
{
    $doctors = Doctor::remember(59) // chach this query for 59 minutes
        ->select(["id", "updated_at"]) 
        // you may want to add where clauses here according to your needs
        ->orderBy("id", "desc")
        ->take(50000) // each Sitemap file must have no more than 50,000 URLs and must be no larger than 10MB
        ->get();

    $patients = Patient::remember(59) // chach this query for 59 minutes
        ->select(["id", "updated_at"]) 
        // you may want to add where clauses here according to your needs
        ->orderBy("id", "desc")
        ->take(50000) // each Sitemap file must have no more than 50,000 URLs and must be no larger than 10MB
        ->get();

    $content = View::make('sitemap', ['doctors' => $doctors, 'patients' => $patients]);
    return Response::make($content)->header('Content-Type', 'text/xml;charset=utf-8');
}

in views/sitemap.blade.php file..

<?php echo '<?xml version="1.0" encoding="UTF-8"?>' ?>

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@foreach($doctors as $doctor)
    <url>
        <loc>{{ URL::route("doctors.show", [$doctor->id]) }}</loc>
        <lastmod>{{ gmdate(DateTime::W3C, strtotime($doctor->updated_at)) }}</lastmod>
        <changefreq>daily</changefreq>
        <priority>1.0</priority>
    </url>
@endforeach

@foreach($patients as $patient)
    <url>
        <loc>{{ URL::route("patients.show", [$patient->id]) }}</loc>
        <lastmod>{{ gmdate(DateTime::W3C, strtotime($patient->updated_at)) }}</lastmod>
        <changefreq>daily</changefreq>
        <priority>1.0</priority>
    </url>
@endforeach
</urlset>
Philadelphia answered 15/7, 2015 at 10:29 Comment(0)
P
4

check https://github.com/RoumenDamianoff/laravel-sitemap

A simple sitemap generator for Laravel 4.

Route::get('sitemap', function(){

    // create new sitemap object
    $sitemap = App::make("sitemap");

    // set cache (key (string), duration in minutes (Carbon|Datetime|int), turn on/off (boolean))
    // by default cache is disabled
    $sitemap->setCache('laravel.sitemap', 3600);

    // check if there is cached sitemap and build new only if is not
    if (!$sitemap->isCached())
    {
         // add item to the sitemap (url, date, priority, freq)
         $sitemap->add(URL::to('/'), '2012-08-25T20:10:00+02:00', '1.0', 'daily');
         $sitemap->add(URL::to('page'), '2012-08-26T12:30:00+02:00', '0.9', 'monthly');

         // get all posts from db
         $posts = DB::table('posts')->orderBy('created_at', 'desc')->get();

         // add every post to the sitemap
         foreach ($posts as $post)
         {
            $sitemap->add($post->slug, $post->modified, $post->priority, $post->freq);
         }
    }

    // show your sitemap (options: 'xml' (default), 'html', 'txt', 'ror-rss', 'ror-rdf')
    return $sitemap->render('xml');

});

i have used it. works great!

update #1

to clear the confusion, let's take an example.

let's say i have a blog table with id, title, blog

i have the route as, Route::get('blog/{blog}',['as' => 'blog.show', 'uses' => 'Blog@show'];

first i will fetch the content, by $blogs = DB::table('blog')->get();

$blogs will contain the results.

i will just loop,

foreach($blogs as $i)
{
     $sitemap->add(route('blog.show',[$i->title]), '2014-11-11', '1.0','daily');
}

all my blogs are added in the sitemap.

Pharyngo answered 13/11, 2014 at 5:42 Comment(8)
whats this post table store??Cappuccino
that's an example. you need use your own queries to get the content.Pharyngo
thats i understand this is an example. but i didn't get what is stored in that posts table. then only i can create my query. can u plz tell me what u gave in ur project sitemap? is that table stores urls?Cappuccino
ok.Thanks for the explanation .. one more doubt (plz forgive i'm a newbie to laravel thats y these much doubts). i've downloaded the laravel-sitemap-master.zip file from the github link ur provided. if i store that extract folder inside the app folder of my laravel project. will this code works??Cappuccino
no. you have to install it via composer. if you don't want to install it via composer, there is a hack but a very ugly one and not 100% gurranteed.Pharyngo
I feel like adding home page, about us page etc manually is a waste as your routes are already specified in routes.php. Why can't all this just be done for you...Wrong
I tried this in blog website where i store my blog as HTML content. I have tried to implement this but i havean error--> Incorrect http header content-type: "text/html; charset=UTF-8" (expected: "application/xml") How will i implement this to Automatically Generate Sitemap with LaravelSunbreak
Good explanation, i have my blog content stored as html, users save the content as raw html, how will i show this in sitemap? I have used the above example but i get an errror that my data is not xlmSunbreak

© 2022 - 2024 — McMap. All rights reserved.