لارافيل, Others / 2024-09-16

إنشاء خريطة الموقع Sitemap XML بشكل دايناميكي في لارافيل

إنشاء خريطة الموقع Sitemap XML بشكل دايناميكي في لارافيل

2024-09-16 وقت القراءه : 5 دقائق

واحدة من أهم الأمور التي يجب القيام بها حتى يكون الموقع متوافق مع محركات البحث SEO أن يتم إنشاء ملف sitemap.xml للموقع، مع العلم بأن وجوده لا يضمن أن جميع العناصر الموجوده بداخله سوف يتم أرشفتها وفهرستها، وبالرغم من ذلك يعتبر وجوده مهم.


ما هي مكونات ملف sitemap.xml

يتكون بالأساس من وسم أساسي <url> ويحتوي على مجموعة من الوسوم  أهمها <loc> حيث يجب أن يحتوي على الرابط، مع وجود وسوم إختياريه مثل <lastmod> حيث يشير إلى أخر تعديل، وكذلك <changefreq> ويعني التردد و <priority> ويمثل الأولوية، ويمكن قراءة المزيد عن بروتوكول خريطة الموقع من الموقع الرسمي.


مثال على مكونات صفحة xml

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <url>
      <loc>http://www.example.com/</loc>
      <lastmod>2005-01-01</lastmod>
      <changefreq>monthly</changefreq>
      <priority>0.8</priority>
   </url>
</urlset>


هل من الممكن أن يحتوي الموقع على أكثر من sitemap؟

ما سيتم إرسالة إلى محركات البحث هو ملف واحد sitemap.xml لكن ماذا لو كان  لدينا أكثر من جدول (Articles, Categories, Questions, Tags)، هنا يمكننا إنشاء ملف sitemap.xml لكن يكون دوره كوسيط به روابط sitemap لكل جدول من الجداول مع العلم أن كل sitemap يمكن أن يمكن أن يحتوي حتى 50000 رابط، وذلك حتى يسهل إدارتها وتكون أسهل للقراءه سواء لنا أو لمحركات البحث.


كيف يتم إنشاء خريطة الموقع Sitemap.

الخطوات

إنشاء route

Route::get('/sitemap.xml',  [SitemapController::class, 'index']);

إنشاء sitemapController مع دالة index تقوم بتوجيهنا إلى ملف sitemap.xml

php artisan make:controller SitemapController 
class SitemapController extends Controller
{
    public function index()
    {
        return response()->view('sitemap.index')->header('Content-Type', 'text/xml');;
    }
}

كما تلاحظون أنه يجب تحديد نوع الهيدر بـ text/xml.


إنشاء ملف العرض

 views/sitemap/index.blade.php سيتم تحديد الروابط لكل جدول من جداول قاعدة البيانات، مع الأخذ أنه يجب تحديد نوع الملف بأنه xml.

بمعنى أخر أن الملف هذا بمثابة الملف الوسيط، حيث سيتم به وضع روابط لملفات xml لكل قاعدة من قواعد البيانات

<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <sitemap>
        <loc>http://www.test.test/sitemap.xml/articles</loc>
    </sitemap>
    <sitemap>
        <loc>http://www.test.test/sitemap.xml/categories</loc>
    </sitemap>
    <sitemap>
        <loc>http://www.test.test/sitemap.xml/questions</loc>
    </sitemap>
    <sitemap>
        <loc>http://www.test.test/sitemap.xml/tags</loc>
    </sitemap>
</sitemapindex>

وعند زيارة الرابط http://www.test.test/sitemap.xml

يظهر لدينا هذا الشكل

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<sitemapindex>
<sitemap>
<loc>http://www.test.test/sitemap.xml/articles</loc>
</sitemap>
<sitemap>
<loc>http://www.test.test/sitemap.xml/categories</loc>
</sitemap>
<sitemap>
<loc>http://www.test.test/sitemap.xml/questions</loc>
</sitemap>
<sitemap>
<loc>http://www.test.test/sitemap.xml/tags</loc>
</sitemap>
</sitemapindex>


كما نلاحظ أنه قدمنا بإنشاء رابط لكل قاعدة من قواعد البيانات.

نعود إلى ملف route لإنشاء الروابط لكل رابط من الروابط الموجوده في ملف xml أعلاه

Route::get('/sitemap.xml/articles',  [SitemapController::class, 'articles']);
Route::get('/sitemap.xml/categories',  [SitemapController::class, 'categories']);
Route::get('/sitemap.xml/questions',  [SitemapController::class, 'questions']);
Route::get('/sitemap.xml/tags',  [SitemapController::class, 'tags']);

وفي SitemapController إنشاء الدوال لجلب البيانات من قواعد البيانات وإرسالها لملف blade لكن مع تحديد content type

   public function articles()
    {
        $articles = Article::latest()->get();
        return response()->view('sitemap.articles', [
            'articles' => $articles,
        ])->header('Content-Type', 'text/xml');
    }

    public function categories()
    {
        $categories = Category::all();
        return response()->view('sitemap.categories', [
            'categories' => $categories,
        ])->header('Content-Type', 'text/xml');
    }

    public function questions()
    {
        $questions = Question::latest()->get();
        return response()->view('sitemap.questions', [
            'questions' => $questions,
        ])->header('Content-Type', 'text/xml');
    }

    public function tags()
    {
        $tags = Tag::all();
        return response()->view('sitemap.tags', [
            'tags' => $tags,
        ])->header('Content-Type', 'text/xml');
    }

كما نلاحظ أنه يجب تحديد النوع بـ text/xml من خلال نوع الهيدر.

وفي ملف العرض views/sitemap/articles نقوم بعرض البيانات مع تحديد الترميز والنوع 

<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    @foreach ($articles as $article)
        <url>
            <loc>http://www.test.test/articles/{{ $article->slug }}</loc>
            <lastmod>{{ $article->created_at->tz('UTC')->toAtomString() }}</lastmod>
            <changefreq>weekly</changefreq>
            <priority>0.9</priority>
        </url>
    @endforeach
</urlset>

الأن عند زيارة الرابط نحصل على هذا الشكل


ماذا لو كان لدينا قاعدة بيانات واحده فقط articles.

هنا لا داعي للملف الوسيط الذي قمنه به بتحديد روابط الأقسام بل يتم كتابة كود عرض البيانات مباشرة

//route
Route::get('/sitemap.xml/articles',  [SitemapController::class, 'articles']);
//SitemapController.articles
public function articles()
{
    $articles = Article::latest()->get();
    return response()->view('sitemap.articles', [
        'articles' => $articles,
    ])->header('Content-Type', 'text/xml');
}
sitemap/articles.blade.php
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    @foreach ($articles as $article)
        <url>
            <loc>http://www.test.test/articles/{{ $article->slug }}</loc>
            <lastmod>{{ $article->created_at->tz('UTC')->toAtomString() }}</lastmod>
            <changefreq>weekly</changefreq>
            <priority>0.9</priority>
        </url>
    @endforeach
</urlset>
إضافة تعليق
Loading...