Astroでギャラリーその2

作成:
heroimage

前回のつづき

前回1階層限定のギャラリーを作成したがコンポーネントからコンポーネントを呼ぶ再帰でディレクトリ階層を調べることができることが分かり、getStaticPaths を使わないギャラリーが完成した。

画像一覧
ブログの画像一覧です
画像一覧 favicon https://ubanis.com/gallery
画像一覧

ディレクトリリスト及び画像表示コンポーネント

例によってスタイルシートは省略。

src/components/ImageList.astro

---
import { getImageFiles, getDirectories } from '@utils/fileUtil.ts';
import ImageList from '@components/ImageList.astro';
import MyImage from "@components/MyImage.astro";
import { LOCAL_IMAGE_ROOT, WEB_IMAGE_ROOT } from '@config/config';

const { currentDir } = Astro.props;
const localDir = currentDir + "/";
const thumbnailSize = "96px";
const subDir = (() => {
try {
  return getDirectories(localDir);
}
catch(e) {
  console.log(e)
  return [];
}
})();

const imageSrc: string[] = [];
const imageFiles = (() => {
  try {
    return getImageFiles(localDir);
  } catch (e) {
    console.log(e);
    return [""];
  }
})();

imageFiles.reverse();

for (const s of imageFiles) {
  const imageUrl = WEB_IMAGE_ROOT + localDir.replace(LOCAL_IMAGE_ROOT, "") + s;
  imageSrc.push(imageUrl);
  console.log(imageUrl);
}
---

<div style="display:inline;">
  {
    imageSrc.map((f) => (
      <span class="image">
        <a data-fancybox={localDir} href={f}>
          <MyImage
           src={f}
           width={thumbnailSize}
           height={thumbnailSize}
           alt={f}
          />
        </a>
      </span>
    ))
  }
</div>
{
subDir.map((dir) => (
    <input type="checkbox" name="imagelist" id={`${localDir}${dir}`} class="toggle" />
    <label for={`${localDir}${dir}`} class="Label">{dir}</label>
    <ul class="content">
    { <li> <ImageList currentDir={`${localDir}${dir}`} /> </li> }
    </ul>
    ))
}
  • LOCAL_IMAGE_ROOTは起点になるディレクトリ
  • WEB_IMAGE_ROOTはウェブ上の画像の起点になるディレクトリ

subDir.mapの中でImageListをまた呼び出している。
このループでサブディレクトリすべてを表示する。

画像はsubDirのループ前に現在のディレクトリであるlocalDirにある画像をすべて表示している。

表示ページ

対象ディレクトリ(LOCAL_IMAGE_ROOT)をcurrentDirに指定している。

---
import BaseLayout from "@layouts/BaseLayout.astro";
import ImageList from "@components/ImageList.astro";
import { LOCAL_IMAGE_ROOT } from "@config/config";
---

<BaseLayout description="ブログの画像一覧です">
  <h1>画像一覧</h1>
  <ImageList currentDir={LOCAL_IMAGE_ROOT} />
  <link rel="stylesheet" href="/fancybox/fancybox.css" />
  <script is:inline src="/fancybox/fancybox.umd.js"></script>
</BaseLayout>

最後に

getStaticPaths でやる方法だとこのリスト方式だとリンクの問題があるので不可能なのではないかと思った。
パスを作ること自体は出来そうではある。