Динамически импортировать все изображения из папки в Astro

Я работаю с Астро. В проекте используется довольно много изображений, и я хочу упростить способ добавления новых изображений. Мои маршруты такие:

example.com/pictures/[коллекция]

("[" и "]" обозначают динамический маршрут)

Допустим, например:

example.com/pictures/mixed-tecnique

example.com/pictures/graphite

example.com/pictures/acrylic


В файлеpages/pictures/[collection].astroЯ хочу сделать следующее (или что-то подобное):

      ---
import * as collections from "public/img/collections"

const { collection } = Astro.props
---

{collections[collection].map(imgSrc => <img src={imgSrc} />)}

Так что теперь, чтобы иметь новый маршрут коллекции, мне просто нужно создать новую папку и поместить туда изображения.

Есть ли способ сделать что-то, чтобы достичь того же результата? Заранее спасибо!!

2 ответа

Вот как я добиваюсь:

      ---
const images = await Astro.glob("/src/assets/img/salon/*").then(files => {
  return files.map(file => file.default);
});
---

<div class="swiper">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    {
      images.map(image => (
        <div class="flex items-center justify-center swiper-slide">
          <img
            class="object-contain h-full rounded-lg"
            src={image}
            alt=""
            loading="lazy"
          />
        </div>
      ))
    }
  </div>
  ...
</div>

Если вы используете функцию экспериментальных ресурсов :

      {
  images.map(({ src /* width and height is also available */ }) => (
    <div class="flex items-center justify-center swiper-slide">
      <img
        class="object-contain h-full rounded-lg"
        src={src}
        alt=""
        loading="lazy"
      />
    </div>
  ))
}

Существует множество различных способов реализации такой функции, но вот простой пример использования библиотеки.

      public
  pictures
    mixed-technique
      example.png
      example.png
      example.png
    graphite
      example.png
      example.png
      example.png
    arcylic
      example.png
      example.png
      example.png
      // src/pages/pictures/[collection].astro
---
import fg from 'fast-glob';

export async function getStaticPaths() {
    // get all collection folder paths: 'public/pictures/[collection]'
    const collections: string[] = fg.sync('public/pictures/*', { onlyDirectories: true })

    // Create a new route for every collection
    return collections.map(collection => {

        // Create Route
        return {
            params: {
                // Return folder name of collection as dynamic parameter [collection]
                collection: collection.split('/').pop()
            },
            props: {
                // Return array of all image srcs in collection as prop 'images'
                images: fg.sync(`${collection}/**/*.{png,jpg}`).map(img => img.replace('public/', '/'))
            }
        }
    })
}

export interface Props {
    images: string[];
}

const { collection } = Astro.params

const { images } = Astro.props
---

<html lang="en">
    <head>
        <!-- ... -->
    </head>
    <body>
        { images.map(img => <img src={img}/>) }
    </body>
</html>

Примечание: я использовалfast-globвместоAstro.globилиimport.meta.glob()потому что он может принимать переменную в качестве аргумента (делает эту логику проще/более динамичной) и потому что он возвращает только массив путей к файлам/папкам вместо того, чтобы пытаться вернуть содержимое файла

Другие вопросы по тегам