PowerCMS X ブログ

2024-12-17

重複した URL をビュー(テンプレート・タグ)のみでリストアップする

PowerCMS X における URL

PowerCMS X では、出力するページ・ファイルの URL 設計が非常に柔軟に行えます。

設計によっては異なるオブジェクト(記事・ページ・アセット など)が同じ URL となってしまうケースがありますが、PowerCMS X では基本的に URL が重複しないことが前提となっています。

例えば、「記事A」と「ページB」が「https://example.com/about.html」という同じ URL にページを出力することを許容してしまうと、実際にはどちらのページが表示されるのか?というシステムだけでは判断がつかない状況となります。

同じ URL が複数できてしまったら

そのため、URL マップを作成する際には生成される URL が重複しないように設計する必用があるのですが、設計時には想定していなかった運用が行われると「想定外の重複した URL」が出来てしまうことがあります。

「重複した URL」が出来てしまった場合、URL のコンフリクトを解消する必用があります。

このとき、そもそも重複している URL が存在しているのか?を調査して、存在している場合はそれぞれの URL が「どのモデル」の「どのオブジェクト」のページ・ファイルの URL なのか?を確認したうえで、本来意図していなかった方の URL を変更(もしくはオブジェクトの削除、および URL の物理削除)する対応を行うこととなります。

さて、重複した URL の存在をどのように確認すればよいでしょうか。

重複している URL の一覧を出力する

PowerCMS X では、CMS が出力した URL を全てデータベースに保持しています。

データベースの mt_urlinfo テーブルを GROUP BY することで重複した URL 一覧を取得することが出来ますが、付与されている権限によってはデータベースへのアクセスやそもそもサーバーへのアクセスが難しいケースがあります。

そこで、今回はビュー(テンプレート・タグ)のみで重複した URL の一覧を出力してみます。

ビューによって重複した URL をリストアップしたイメージ

ビュー(テンプレート)[1]

新たにビューを作成し、下記のテンプレート・タグを張り付けて保存してください。

今回のように調査用のビューであればURLマップは作成せず、ビュー編集画面下部の「プレビュー」ボタンで確認するでもよいと思います。

<mt:block regex_replace="'/^\s+$/um',''" remove_blank="1">
<mt:setvarblock name="_base_edit_url"><mt:property name="admin_url">?__mode=view&_type=edit</mt:setvarblock>
<mt:block from_json="_list">[]</mt:block>
<mt:objectloop model="urlinfo" sort_by="urlinfo_url" sort_order="ascend" delete_flag="'0','1'" prefix="urlinfo"><mt:ignore> include_workspaces="all"</mt:ignore>
  <mt:var name="urlinfo_url" setvar="_key">
  <mt:block from_json="_value">{
    "id": "<mt:var name="urlinfo_id">",
    "workspace_id": "<mt:var name="urlinfo_workspace_id">",
    "model": "<mt:var name="urlinfo_model">",
    "object_id": "<mt:var name="urlinfo_object_id">",
    "delete_flag": "<mt:var name="urlinfo_delete_flag">",
    "urlinfo_link" : "<mt:var name="_base_edit_url">&_model=urlinfo&id=<mt:var name="urlinfo_id">",
    "object_link" : "<mt:var name="_base_edit_url">&_model=<mt:var name="urlinfo_model">&id=<mt:var name="urlinfo_object_id">"
  }</mt:block>
  <mt:var name="_list" key="$_key" setvar="_item">
  <mt:setvar name="_item" function="push" value="$_value">
  <mt:setvar name="_list" key="$_key" value="$_item">
</mt:objectloop>
<mt:block from_json="_duplicated">[]</mt:block>
<mt:loop name="_list">
  <mt:count name="__value__" setvar="count">
  <mt:if name="count" ge="2">
    <mt:setvar name="_duplicated" key="$__key__" value="$__value__">
  </mt:if>
</mt:loop>
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <link href="<mt:var name="application_path">assets/css/bootstrap.min.css" rel="stylesheet">
    <title>Duplicate URLs</title>
  </head>
  <body>
    <main class="col-md-12 pt-3">
      <h1 class="mb-4">Duplicate URLs (<mt:count name="_duplicated">)</h1>
      <mt:loop name="_duplicated">
        <h2 class="h3"><mt:var name="__key__"> (<mt:count name="__value__">)</h2>
        <div class="ml-4">
          <table class="table table-striped table-sm listing-table">
            <thead>
              <tr>
                <th class="text-nowrap p-2">ID</th>
                <th class="text-nowrap p-2">Model</th>
                <th class="text-nowrap p-2">Object ID</th>
                <th class="text-nowrap p-2">Delete flag</th>
                <th class="text-nowrap p-2">Workspace ID</th>
                <th class="text-nowrap p-2">Urlinfo Link</th>
                <th class="text-nowrap p-2">Object Link</th>
              </tr>
            </thead>
            <tbody>
              <mt:loop name="__value__">
                <tr>
                  <td class="p-2 text-right"><mt:var name="id"></td>
                  <td class="p-2 text-right"><mt:var name="model"></td>
                  <td class="p-2 text-right"><mt:var name="object_id"></td>
                  <td class="p-2 text-right"><mt:var name="delete_flag"></td>
                  <td class="p-2 text-right"><mt:var name="workspace_id"></td>
                  <td class="p-2"><a href="<mt:var name="urlinfo_link">" target="_blank" class="text-wrap"><mt:var name="urlinfo_link"></a></td>
                  <td class="p-2"><a href="<mt:var name="object_link">" target="_blank" class="text-wrap"><mt:var name="object_link"></a></td>
                </tr>
              </mt:loop>
            </tbody>
          </table>
        </div>
      </mt:loop>
    </main>
  </body>
</html>
</mt:block>

上記テンプレートでは、ビューを作成したスペースに所属する URL が対象となります。mt:objectloop タグに include_workspaces="all" 属性を追記することで全てのスペースの URL が対象となります。

また、URL オブジェクトを全件ロードしてからビュー側で重複チェックを行っているため、URL オブジェクトの件数が多量の場合に処理が重くなることがあります。 [2]

脚注

  1. 記事執筆時点で最新の PowerCMS X ver.3.62 で動作確認しています。[^1]
  2. mt:countgroupby タグでの実装も検討しましたが、HAVING 句による絞り込みが行えなかったため断念しました。 [^2]

カテゴリー:トラブルシューティング | テンプレート作成Tips | サポート

投稿者:たはかし

ブログ内検索

アーカイブ


日本語
ふりがな付き
English
简体中文
繁體中文
한국어