*/ public static function alternates(Model $record, string $type, string $slugField = 'slug'): array { $alternates = []; foreach (array_keys(config('locales.supported')) as $locale) { $slug = $record->getTranslation($slugField, $locale, useFallbackLocale: false); // A locale without its own slug has no URL of its own — emitting // one would advertise a page that does not exist. if (blank($slug)) { continue; } $alternates[$locale] = self::path($type, $locale, (string) $slug); } return $alternates; } /** * Absolute URLs for the same set, ready to drop into ``. * * @return array */ public static function absoluteAlternates(Model $record, string $type, string $slugField = 'slug'): array { return array_map( fn (string $path) => rtrim(config('site.url'), '/').$path, self::alternates($record, $type, $slugField), ); } /** * The path a record occupies on the public site, e.g. "/ca/projectes/foo". */ public static function path(string $type, string $locale, string $slug): string { $segments = []; if ($locale !== config('locales.default') || config('site.prefix_default_locale')) { $segments[] = $locale; } if ($prefix = config("site.paths.{$type}.{$locale}")) { $segments[] = $prefix; } $segments[] = $slug; return '/'.implode('/', array_filter($segments, fn ($s) => $s !== '')); } }