Программирование

Перевод маршрутов для Astro Content Collections или подстраниц

Артур Сопельник
#astro#i18n#маршрутизация

Помимо официальной документации по переводу маршрутов, которую я написал, я хотел бы объяснить шаги по переводу маршрутов для коллекций контента и подстраниц.

Смотрите пример ниже:

// ui.ts

export const routes = {
  de: {
    services: "услуги",
    blog: "блог", // индекс коллекции контента
    "blog.how-to-become-a-scrum-master": "blog.kak-stat-scrum-master",
  },
  fr: {
    services: "услуги",
    blog: "блог", // индекс коллекции контента
    "blog.how-to-become-a-scrum-master": "blog.kak-stat-scrum-master",
  },
};

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

// utils.ts

// Добавьте замену точки/косой черты для translatedPath
export function useTranslatedPath(lang: keyof typeof ui) {
  return function translatePath(path: string, l: string = lang) {
    const pathName = path.replaceAll("/", "");
    const hasTranslation =
      defaultLang !== l &&
      routes[l] !== undefined &&
      routes[l][pathName] !== undefined;
    const translatedPath = hasTranslation ? "/" + routes[l][pathName] : path;
    const translatedPathReplaced = translatedPath.replaceAll(".", "/");

    return !showDefaultLang && l === defaultLang
      ? translatedPathReplaced
      : `/${l}${translatedPathReplaced}`;
  };
}

// Добавьте поддержку многоуровневых маршрутов, проверяя весь путь и пропуская каталог языка
export function getRouteFromUrl(url: URL): string | undefined {
  const pathname = new URL(url)?.pathname;

  const path = pathname
    ?.split("/")
    .filter(Boolean)
    .filter((part) => !Object.keys(languages).includes(part))
    .join(".");

  if (!path) {
    return undefined;
  }

  const currentLang = getLangFromUrl(url);

  if (defaultLang === currentLang) {
    const route = Object.values(routes)[0];
    const pathTyped = path as keyof typeof route;
    return pathTyped in route ? pathTyped : undefined
  }

  const getKeyByValue = (
    obj: Record<string, string>,
    value: string,
  ): string | undefined => {
    return Object.keys(obj).find((key) => obj[key] === value);
  };

  const reversedKey = getKeyByValue(routes[currentLang], path);

  if (reversedKey !== undefined) {
    return reversedKey;
  }

  return undefined;
}

Перевод маршрутов с поддержкой trailingSlash и base

Официальная документация и указанный рецепт работают только без настройки страницы trailingSlash или отклонения от base.

Например, если вы хотите использовать trailingSlash: always, вы можете найти интеграцию исходный код здесь. Или живой просмотр.