LoginSignup
1
0

More than 3 years have passed since last update.

【laravel】sitemap.xmlの更新をしたくない気持ち(※未解決)

Posted at

それはどんな気持ちか

  • ルートを変更する度にsitemapの更新したくないな
  • 特定のミドルウェアルートグループのgetルートが全てsitemap.xmlに勝手に登録されたらいいのにな

※ 未解決

全てのルートの取得方法の確認も合わせてやってみます。

やってみる

想定する流れ

  1. ルートを取得する
  2. sitemap.xmlに出力

ルートを取得する

参考

このコマンドでやっていることが参考になりそうなので、参考にしてみる。


$ php artisan route:list

Illuminate\Foundation\Console\RouteListCommand を読む。

RouteListCommand
// ※ use Illuminate\Routing\Router;


/**
 * Create a new route command instance.
 *
 * @param  \Illuminate\Routing\Router  $router
 * @return void
 */
public function __construct(Router $router)
{
    parent::__construct();

    $this->router = $router;
}

/**
 * Execute the console command.
 *
 * @return void
 */
public function handle()
{
    if (empty($this->router->getRoutes())) {
        return $this->error("Your application doesn't have any routes.");
    }

    if (empty($routes = $this->getRoutes())) {
        return $this->error("Your application doesn't have any routes matching the given criteria.");
    }

    $this->displayRoutes($routes);
}

$this->router->getRoutes() で全てのルートを取得し、ルート毎に属性(name,middlewareなど)をそれぞれ処理している。

今回はミドルウェアとメソッドが欲しいのでそれらを確認してみます。

  1. ミドルウェアの取得は

    RouteListCommand
    /**
     * Get before filters.
     *
     * @param  \Illuminate\Routing\Route  $route
     * @return string
     */
    protected function getMiddleware($route)
    {
        return collect($route->gatherMiddleware())->map(function ($middleware) {
            return $middleware instanceof Closure ? 'Closure' : $middleware;
        })->implode(',');
    }
    

    ルート毎にミドルウェアを取得(gatherMiddleware)してクロージャかの判断などしつつコレクション化しているようです。

  2. メソッドの取得は

    RouteListCommand
    /**
     * Get the route information for a given route.
     *
     * @param  \Illuminate\Routing\Route  $route
     * @return array
     */
    protected function getRouteInformation(Route $route)
    {
        return $this->filterRoute([
            'domain' => $route->domain(),
            'method' => implode('|', $route->methods()),
            'uri'    => $route->uri(),
            'name'   => $route->getName(),
            'action' => ltrim($route->getActionName(), '\\'),
            'middleware' => $this->getMiddleware($route),
        ]);
    }
    

    $route->methods() で取れるようです。

取得してみる

とりあえずコントローラに直接書いてみます。

SiteMapController
<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Router;

class SiteMapController extends Controller
{

    /**
     * @var Router
     */
    private $router;

    public function __construct(Router $router)
    {
        $this->router = $router;
    }

    public function index()
    {
        $uris = [];
        foreach ($this->router->getRoutes() as $route) {

            if (!in_array('front', $route->gatherMiddleware()) || !in_array('GET', $route->methods()))
                continue;

            $uris[] = $route->uri;
        }
    }
}

取得出来る$urisはこんなかんじになる

適当な例
[
  0 => "/"
  1 => "article/{Article}"
  2 => "neko"
  3 => "inu"
]

問題

ルートパラメータの存在するルートを全て取得する方法を見つけられていない、のでここでは一度無視する🐛
モデル結合ルートに限れば、既に存在するURIは定義されているということになるはずなので、その辺でうまいこと取得出来ないだろうかと考えています。
もう少し検証しますが、いい方法があったら教えて欲しいです。

sitemap.xmlに出す

SiteMapController
<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Response;

class SiteMapController extends Controller
{

    /**
     * @var Router
     */
    private $router;

    public function __construct(Router $router)
    {
        $this->router = $router;
    }

    public function index()
    {
        $uris = [];
        foreach ($this->router->getRoutes() as $key => $route) {

            if (!in_array('front', $route->gatherMiddleware()) || !in_array('GET', $route->methods()))
                continue;

            $uris[] = $route->uri;
        }

        $view = view('site_map.index', compact('uris'));
        return Response::make($view, '200')->header('Content-Type', 'application/xml');

    }
}

site_map.index
<?php echo '<?xml version="1.0" encoding="UTF-8" ?>' . "\n"; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

    @foreach($uris as $uri)
        <url>
            <loc>{{ url($uri) }}</loc>
            <changefreq>daily</changefreq>
        </url>
    @endforeach

</urlset>

おわり

楽したいのでもっとうまい方法考えます。
ただ些細な更新ストレスを減らすための行為で制限を増やすと逆説的にストレスが増えちゃいそうなので、laravelが素直に出来る範囲ぐらいの程々で諦めるべきかもしれません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0