😆Laravel 9 Generate and Read Sitemap XML File Tutorial (ok)
https://www.positronx.io/laravel-generate-and-read-sitemap-xml-file-tutorial/
Site map có 2 loại, loại thứ nhất là xml, loại thứ 2 là html.
Ví dụ 1: loại thứ nhất là xml
composer require roumen/sitemap
// Link: https://github.com/LaraPalCom/laravel-sitemap
C:\xampp82\htdocs\testvn\config\app.php
'providers' => [
...
Laravelium\Sitemap\SitemapServiceProvider::class
...
]
C:\xampp82\htdocs\testvn\routes\web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('post-detail/{id}',[PostController::class,'detail'])->name('post.detail');
C:\xampp82\htdocs\testvn\app\Models\Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillables = [
'detail',
'slug'
];
}
php artisan make:command CreateSiteMap --command=sitemap:create
C:\xampp82\htdocs\testvn\app\Console\Commands\CreateSiteMap.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Carbon\Carbon;
class CreateSiteMap extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'sitemap:create';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$sitemap = \App::make('sitemap');
// add home pages mặc định
$sitemap->add(\URL::to('/'), Carbon::now(), '1.0', 'daily');
// add bài viết
$posts = \DB::table('posts')
->orderBy('created_at', 'desc')
->get();
foreach ($posts as $post) {
$sitemap->add(route('post.detail', [$post->slug]), $post->created_at, '0.6', 'daily');
}
// lưu file và phân quyền
$sitemap->store('xml', 'sitemap');
if (\File::exists(public_path() . '/sitemap.xml')) {
chmod(public_path() . '/sitemap.xml', 0777);
}
}
}
C:\xampp82\htdocs\testvn\app\Http\Controllers\PostController.php
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}
public function detail(Post $post)
{
}
}
C:\xampp82\htdocs\testvn\public\sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/vendor/sitemap/styles/xml.xsl" type="text/xsl"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url>
<loc>https://test.vn</loc>
<priority>1.0</priority>
<lastmod>2023-04-17T16:34:10+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://test.vn/post-detail/laboriosam</loc>
<priority>0.6</priority>
<lastmod>2023-04-17T15:52:13+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://test.vn/post-detail/eligendi-sed</loc>
<priority>0.6</priority>
<lastmod>2023-04-17T15:52:13+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://test.vn/post-detail/aut-cum</loc>
<priority>0.6</priority>
<lastmod>2023-04-17T15:52:13+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://test.vn/post-detail/aut-nihil</loc>
<priority>0.6</priority>
<lastmod>2023-04-17T15:52:13+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://test.vn/post-detail/ex-accusamus</loc>
<priority>0.6</priority>
<lastmod>2023-04-17T15:52:13+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://test.vn/post-detail/reiciendis</loc>
<priority>0.6</priority>
<lastmod>2023-04-17T15:52:13+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://test.vn/post-detail/animi-est-unde</loc>
<priority>0.6</priority>
<lastmod>2023-04-17T15:52:13+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://test.vn/post-detail/possimus</loc>
<priority>0.6</priority>
<lastmod>2023-04-17T15:52:13+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://test.vn/post-detail/consequatur</loc>
<priority>0.6</priority>
<lastmod>2023-04-17T15:52:13+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://test.vn/post-detail/voluptates</loc>
<priority>0.6</priority>
<lastmod>2023-04-17T15:52:13+00:00</lastmod>
<changefreq>daily</changefreq>
</url>
</urlset>
C:\xampp82\htdocs\testvn\database\factories\PostFactory.php
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class PostFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
$detail = $this->faker->text(15);
// $slug = str_slug($detail, '-');
$slug = Str::slug($detail, '-');
return [
'detail' => $detail,
'slug' => $slug
];
}
}
C:\xampp82\htdocs\testvn\database\seeders\DatabaseSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
use App\Models\Post;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
User::factory(10)->create();
Post::factory(10)->create();
}
}
C:\xampp82\htdocs\testvn\database\migrations\2023_04_17_130047_create_posts_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('detail');
$table->string('slug');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
Ví dụ 2: loại thứ loại thứ nhất là xml
php artisan migrate --seed
C:\xampp81\htdocs\testcn\app\Models\Blog.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Blog extends Model
{
use HasFactory;
protected $fillable = [
'url',
'description'
];
}
C:\xampp81\htdocs\testcn\database\migrations\2023_04_17_092922_create_blogs_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('blogs', function (Blueprint $table) {
$table->id();
$table->string('url');
$table->text('description');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('blogs');
}
};
C:\xampp81\htdocs\testcn\database\factories\BlogFactory.php
<?php
namespace Database\Factories;
use App\Models\Blog;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Blog>
*/
class BlogFactory extends Factory
{
protected $model = Blog::class;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'url' => $this->faker->randomNumber($nbDigits = NULL, $strict = false),
'description' => $this->faker->text
];
}
}
C:\xampp81\htdocs\testcn\database\seeders\DatabaseSeeder.php
<?php
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
\App\Models\Blog::factory(30)->create();
// \App\Models\User::factory()->create([
// 'name' => 'Test User',
// 'email' => 'test@example.com',
// ]);
}
}
C:\xampp81\htdocs\testcn\app\Http\Controllers\SitemapXmlController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Blog;
class SitemapXmlController extends Controller
{
public function index()
{
$posts = Blog::all();
return response()->view('index', [
'posts' => $posts
])->header('Content-Type', 'text/xml');
}
}
C:\xampp81\htdocs\testcn\routes\web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\SitemapXmlController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('/sitemap.xml', [SitemapXmlController::class, 'index']);
C:\xampp81\htdocs\testcn\resources\views\index.blade.php
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@foreach ($posts as $post)
<url>
<loc>{{ url('/') }}/page/{{ $post->url }}</loc>
<lastmod>{{ $post->created_at->tz('UTC')->toAtomString() }}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
@endforeach
</urlset>
Last updated