リンクされていないページをリストアップするスクリプト
概要
このコードをスクラップボックス内の任意のJS実行環境やカスタムスクリプトとして利用することで、プロジェクト内の「孤立ページ」を一覧表示できます。
スクラップボックスの REST API を利用してプロジェクト内の全ページのタイトルとリンク情報を取得し、他ページからリンクされていないページを抽出してポップアップウィンドウで表示します。
アルゴリズム
1. データの取得
指定したプロジェクト名に対して、https://scrapbox.io/api/pages/:projectname/search/titles エンドポイントからページ情報を取得します。
応答ヘッダの X-Following-Id を利用して、ページ一覧を1000件ずつ順次取得する仕組みです。
2. リンク情報の解析
各ページに記載されている links 配列内のリンク先タイトルをすべてセットに保存し、どのページからも参照されているタイトルを記録します。
3. リンクされていないページの抽出
全ページの中から、自身のタイトルがいずれのリンクリストにも存在しないページをフィルタして抽出します。
4. ポップアップウィンドウで結果表示
抽出されたページタイトル一覧をHTMLリストとしてポップアップウィンドウに書き出します。
ポップアップがブロックされた場合は、エラーメッセージで通知します。
参考
スクリプト
code:script.js
(async function() {
// プロジェクト名を設定してください
const projectName = "TOMIOKARIO";
const baseUrl = https://scrapbox.io/api/pages/${projectName}/search/titles;
// 全ページ情報を格納する配列
let allPages = [];
// 次ページの取得用 URL(最初はベースURL)
let nextUrl = baseUrl;
// ページがなくなるまでループで全件取得
while (nextUrl) {
try {
const response = await fetch(nextUrl);
if (!response.ok) {
console.error(HTTPエラー: ${response.status});
break;
}
const pages = await response.json();
allPages.push(...pages);
// 応答ヘッダからX-Following-Idを取得し、次のURLを生成
const followingId = response.headers.get('X-Following-Id');
if (followingId) {
nextUrl = ${baseUrl}?followingId=${followingId};
} else {
nextUrl = null;
}
} catch (error) {
console.error("データ取得中にエラーが発生しました:", error);
break;
}
}
// 他のページからリンクされているページタイトルをセットに追加
const linkedPagesSet = new Set();
allPages.forEach(page => {
page.links.forEach(linkTitle => {
linkedPagesSet.add(linkTitle);
});
});
// リンクされていないページ(=自ページのタイトルがどこにも出現していないもの)を抽出
const notLinkedPages = allPages.filter(page => !linkedPagesSet.has(page.title));
// 結果のHTMLを作成
let resultHtml = `
<html>
<head>
<meta charset="utf-8">
<title>リンクされていないページ一覧</title>
</head>
<body>
<h1>リンクされていないページ一覧</h1>
<ul>
`;
notLinkedPages.forEach(page => {
resultHtml += <li>${page.title}</li>;
});
resultHtml += `
</ul>
</body>
</html>
`;
// ポップアップウィンドウで結果表示(ウィンドウサイズなどは必要に応じて調整してください)
const popup = window.open("", "UnlinkedPages", "width=400,height=600,scrollbars=yes");
if (popup) {
popup.document.open();
popup.document.write(resultHtml);
popup.document.close();
} else {
// ポップアップがブロックされている場合は代替としてalertで通知
alert("ポップアップウィンドウの表示がブロックされました。ブラウザのポップアップブロック設定を確認してください。");
}
})();