120 lines
3.3 KiB
Swift
120 lines
3.3 KiB
Swift
|
import Foundation
|
||
|
|
||
|
protocol LanguageIdentifiable {
|
||
|
|
||
|
var languageIdentifier: String { get }
|
||
|
|
||
|
var title: String { get }
|
||
|
}
|
||
|
|
||
|
protocol LanguageContainer {
|
||
|
|
||
|
associatedtype LocalizedContainer: LanguageIdentifiable
|
||
|
|
||
|
var languages: [LocalizedContainer] { get }
|
||
|
|
||
|
}
|
||
|
|
||
|
protocol LocalizedMetadataContainer {
|
||
|
|
||
|
associatedtype MetadataType: LanguageContainer
|
||
|
|
||
|
var metadata: MetadataType { get }
|
||
|
|
||
|
func hasContent(for language: String) -> Bool
|
||
|
}
|
||
|
|
||
|
// MARK: Default implementations
|
||
|
|
||
|
extension LocalizedMetadataContainer {
|
||
|
|
||
|
func hasContent(for language: String) -> Bool {
|
||
|
true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// MARK: Extensions
|
||
|
|
||
|
extension LocalizedMetadataContainer {
|
||
|
|
||
|
func localized(for language: String) -> MetadataType.LocalizedContainer {
|
||
|
metadata.localized(for: language)
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
The localized title of the element.
|
||
|
|
||
|
This title is used as large text in overview pages, or as the `<h1>` title on pages. If no separate link preview title is specified using a localized `linkPreview.title`, then this value is also used for link previews.
|
||
|
*/
|
||
|
func title(for language: String) -> String {
|
||
|
localized(for: language).title
|
||
|
}
|
||
|
|
||
|
|
||
|
func nextLanguage(for languageIdentifier: String) -> String? {
|
||
|
let langs = metadata.languages.map { $0.languageIdentifier }
|
||
|
guard let index = langs.firstIndex(of: languageIdentifier) else {
|
||
|
return nil
|
||
|
}
|
||
|
for i in 1..<langs.count {
|
||
|
let next = langs[(index + i) % langs.count]
|
||
|
guard hasContent(for: next) else {
|
||
|
continue
|
||
|
}
|
||
|
guard next != languageIdentifier else {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
return next
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extension LanguageContainer {
|
||
|
|
||
|
var languageIdentifiers: [String] {
|
||
|
languages.map { $0.languageIdentifier }
|
||
|
}
|
||
|
|
||
|
#warning("Throw better error for missing language")
|
||
|
func localized(for language: String) -> LocalizedContainer {
|
||
|
languages.first { $0.languageIdentifier == language }!
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
The localized title of the element.
|
||
|
|
||
|
This title is used as large text in overview pages, or as the `<h1>` title on pages. If no separate link preview title is specified using a localized `linkPreview.title`, then this value is also used for link previews.
|
||
|
*/
|
||
|
func title(for language: String) -> String {
|
||
|
localized(for: language).title
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extension LocalizedMetadataContainer where Self: SiteElement, Self.MetadataType.LocalizedContainer: LinkPreviewMetadataProvider {
|
||
|
|
||
|
private func linkPreviewImageFileName(for language: String) -> String? {
|
||
|
if let fileName = localized(for: language).linkPreview?.image {
|
||
|
return fileName
|
||
|
}
|
||
|
// Check for the existence of a localized thumbnail
|
||
|
let fileName = Self.thumbnailFileNameLocalized(for: language)
|
||
|
if inputFolder.appendingPathComponent(fileName).exists {
|
||
|
return fileName
|
||
|
}
|
||
|
let defaultThumbnail = Self.defaultThumbnailFileName
|
||
|
if inputFolder.appendingPathComponent(defaultThumbnail).exists {
|
||
|
return defaultThumbnail
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func linkPreviewImage(for language: String) -> String? {
|
||
|
guard let fileName = linkPreviewImageFileName(for: language) else {
|
||
|
return nil
|
||
|
}
|
||
|
return "/\(path)/\(fileName)"
|
||
|
}
|
||
|
}
|