2022-08-19 18:05:06 +02:00
|
|
|
import Foundation
|
|
|
|
|
|
|
|
extension Element {
|
|
|
|
|
|
|
|
/**
|
|
|
|
Metadata localized for a specific language.
|
|
|
|
*/
|
|
|
|
struct LocalizedMetadata {
|
|
|
|
|
|
|
|
static let moreLinkDefaultText = "DefaultMoreText"
|
|
|
|
|
|
|
|
/**
|
|
|
|
The language for which the content is specified.
|
|
|
|
- Note: This field is mandatory
|
|
|
|
*/
|
|
|
|
let language: String
|
|
|
|
|
|
|
|
/**
|
|
|
|
- Note: This field is mandatory
|
|
|
|
The title used in the page header.
|
|
|
|
*/
|
|
|
|
let title: String
|
|
|
|
|
|
|
|
/**
|
|
|
|
The subtitle used in the page header.
|
|
|
|
*/
|
|
|
|
let subtitle: String?
|
|
|
|
|
|
|
|
/**
|
|
|
|
The description text used in the page header.
|
|
|
|
*/
|
|
|
|
let description: String?
|
|
|
|
|
|
|
|
/**
|
|
|
|
The title to use for the link preview.
|
|
|
|
|
|
|
|
If `nil` is specified, then the localized element `title` is used.
|
|
|
|
*/
|
|
|
|
let linkPreviewTitle: String
|
|
|
|
|
|
|
|
/**
|
|
|
|
The file name of the link preview image.
|
|
|
|
- Note: The image must be located in the element folder.
|
2022-08-26 17:40:51 +02:00
|
|
|
- Note: If `nil` is specified, then the (localized) thumbnail is used, if available.
|
2022-08-19 18:05:06 +02:00
|
|
|
*/
|
2022-08-26 17:40:51 +02:00
|
|
|
let linkPreviewImage: String?
|
2022-08-19 18:05:06 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
The description text for the link preview.
|
|
|
|
- Note: If `nil` is specified, then first the (localized) element `subtitle` is used.
|
|
|
|
If this is `nil` too, then the localized `description` of the element is used.
|
|
|
|
*/
|
|
|
|
let linkPreviewDescription: String
|
|
|
|
|
|
|
|
/**
|
|
|
|
The text on the link to show the section page when previewing multiple sections on an overview page.
|
|
|
|
- Note: If this value is inherited from the parent, if it is not defined. There must be at least one
|
|
|
|
element in the path that defines this property.
|
|
|
|
*/
|
|
|
|
let moreLinkText: String
|
|
|
|
|
|
|
|
/**
|
|
|
|
The text on the back navigation link of **contained** elements.
|
|
|
|
|
|
|
|
This text does not appear on the section page, but on the pages contained within the section.
|
|
|
|
*/
|
|
|
|
let backLinkText: String
|
|
|
|
|
2022-08-26 17:40:51 +02:00
|
|
|
/**
|
|
|
|
The text on the back navigation link of the **parent** element.
|
|
|
|
|
|
|
|
This text appears on the section page, but not on the pages contained within the section.
|
|
|
|
*/
|
|
|
|
let parentBackLinkText: String
|
|
|
|
|
2022-08-19 18:05:06 +02:00
|
|
|
/**
|
|
|
|
The text to show as a title for placeholder boxes
|
|
|
|
|
|
|
|
Placeholders are included in missing pages.
|
|
|
|
- Note: If no value is specified, then this property is inherited from the parent. The root element must specify this property.
|
|
|
|
*/
|
|
|
|
let placeholderTitle: String
|
|
|
|
|
|
|
|
/**
|
|
|
|
The text to show as a description for placeholder boxes
|
|
|
|
|
|
|
|
Placeholders are included in missing pages.
|
|
|
|
- Note: If no value is specified, then this property is inherited from the parent. The root element must specify this property.
|
|
|
|
*/
|
|
|
|
let placeholderText: String
|
|
|
|
|
|
|
|
/**
|
|
|
|
An optional suffix to add to the title on a page.
|
|
|
|
|
|
|
|
This can be useful to express a different author, project grouping, etc.
|
|
|
|
*/
|
|
|
|
let titleSuffix: String?
|
|
|
|
|
|
|
|
/**
|
|
|
|
An optional suffix to add to the thumbnail title of a page.
|
|
|
|
|
|
|
|
This can be useful to express a different author, project grouping, etc.
|
|
|
|
*/
|
|
|
|
let thumbnailSuffix: String?
|
|
|
|
|
|
|
|
/**
|
|
|
|
A text to place in the top right corner of a large thumbnail.
|
|
|
|
|
|
|
|
The text should be a very short string to fit into the corner, like `soon`, or `draft`
|
|
|
|
|
|
|
|
- Note: This property is ignored if `thumbnailStyle` is not `large`.
|
|
|
|
*/
|
|
|
|
let cornerText: String?
|
|
|
|
|
|
|
|
/**
|
|
|
|
The external url to use instead of automatically generating the page.
|
|
|
|
|
|
|
|
This property can be used for links to other parts of the site, like additional services.
|
|
|
|
It can also be set to manually write a page.
|
|
|
|
*/
|
|
|
|
let externalUrl: String?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension Element.LocalizedMetadata {
|
|
|
|
|
2022-08-26 17:40:51 +02:00
|
|
|
init?(atRoot folder: URL, data: GenericMetadata.LocalizedMetadata) {
|
2022-08-19 18:05:06 +02:00
|
|
|
// Go through all elements and check them for completeness
|
|
|
|
// In the end, check that all required elements are present
|
|
|
|
var isComplete = true
|
|
|
|
func markAsIncomplete() {
|
|
|
|
isComplete = false
|
|
|
|
}
|
|
|
|
let source = "root"
|
2022-08-26 17:40:51 +02:00
|
|
|
self.language = log
|
2022-08-19 18:05:06 +02:00
|
|
|
.required(data.language, name: "language", source: source)
|
|
|
|
.ifNil(markAsIncomplete) ?? ""
|
2022-08-26 17:40:51 +02:00
|
|
|
self.title = log
|
2022-08-19 18:05:06 +02:00
|
|
|
.required(data.title, name: "title", source: source)
|
|
|
|
.ifNil(markAsIncomplete) ?? ""
|
|
|
|
self.subtitle = data.subtitle
|
|
|
|
self.description = data.description
|
|
|
|
self.linkPreviewTitle = data.linkPreviewTitle ?? data.title ?? ""
|
2022-08-26 17:40:51 +02:00
|
|
|
self.linkPreviewImage = log
|
|
|
|
.linkPreviewThumbnail(customFile: data.linkPreviewImage, for: language, in: folder, source: source)
|
2022-08-29 17:22:24 +02:00
|
|
|
let linkPreviewDescription = data.linkPreviewDescription ?? data.description ?? data.subtitle
|
2022-08-26 17:40:51 +02:00
|
|
|
self.linkPreviewDescription = log
|
2022-08-19 18:05:06 +02:00
|
|
|
.required(linkPreviewDescription, name: "linkPreviewDescription", source: source)
|
|
|
|
.ifNil(markAsIncomplete) ?? ""
|
|
|
|
self.moreLinkText = data.moreLinkText ?? Element.LocalizedMetadata.moreLinkDefaultText
|
2022-08-26 17:40:51 +02:00
|
|
|
self.backLinkText = log
|
2022-08-19 18:05:06 +02:00
|
|
|
.required(data.backLinkText, name: "backLinkText", source: source)
|
|
|
|
.ifNil(markAsIncomplete) ?? ""
|
2022-08-26 17:40:51 +02:00
|
|
|
self.parentBackLinkText = "" // Root has no parent
|
|
|
|
self.placeholderTitle = log
|
2022-08-19 18:05:06 +02:00
|
|
|
.required(data.placeholderTitle, name: "placeholderTitle", source: source)
|
|
|
|
.ifNil(markAsIncomplete) ?? ""
|
2022-08-26 17:40:51 +02:00
|
|
|
self.placeholderText = log
|
2022-08-19 18:05:06 +02:00
|
|
|
.required(data.placeholderText, name: "placeholderText", source: source)
|
|
|
|
.ifNil(markAsIncomplete) ?? ""
|
|
|
|
self.titleSuffix = data.titleSuffix
|
2022-08-26 17:40:51 +02:00
|
|
|
self.thumbnailSuffix = log.unused(data.thumbnailSuffix, "thumbnailSuffix", source: source)
|
|
|
|
self.cornerText = log.unused(data.cornerText, "cornerText", source: source)
|
|
|
|
self.externalUrl = log.unexpected(data.externalUrl, name: "externalUrl", source: source)
|
2022-08-19 18:05:06 +02:00
|
|
|
|
|
|
|
guard isComplete else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-26 17:40:51 +02:00
|
|
|
init?(folder: URL, data: GenericMetadata.LocalizedMetadata, source: String, parent: Element.LocalizedMetadata) {
|
2022-08-19 18:05:06 +02:00
|
|
|
// Go through all elements and check them for completeness
|
|
|
|
// In the end, check that all required elements are present
|
|
|
|
var isComplete = true
|
|
|
|
func markAsIncomplete() {
|
|
|
|
isComplete = false
|
|
|
|
}
|
|
|
|
self.language = parent.language
|
2022-08-26 17:40:51 +02:00
|
|
|
self.title = log
|
2022-08-19 18:05:06 +02:00
|
|
|
.required(data.title, name: "title", source: source)
|
|
|
|
.ifNil(markAsIncomplete) ?? ""
|
|
|
|
self.subtitle = data.subtitle
|
|
|
|
self.description = data.description
|
|
|
|
self.linkPreviewTitle = data.linkPreviewTitle ?? data.title ?? ""
|
2022-08-26 17:40:51 +02:00
|
|
|
self.linkPreviewImage = log
|
|
|
|
.linkPreviewThumbnail(customFile: data.linkPreviewImage, for: language, in: folder, source: source)
|
2022-08-29 17:22:24 +02:00
|
|
|
let linkPreviewDescription = data.linkPreviewDescription ?? data.description ?? data.subtitle
|
2022-08-26 17:40:51 +02:00
|
|
|
self.linkPreviewDescription = log
|
2022-08-19 18:05:06 +02:00
|
|
|
.required(linkPreviewDescription, name: "linkPreviewDescription", source: source)
|
|
|
|
.ifNil(markAsIncomplete) ?? ""
|
2022-08-26 17:40:51 +02:00
|
|
|
self.moreLinkText = log.moreLinkText(data.moreLinkText, parent: parent.moreLinkText, source: source)
|
2022-08-19 18:05:06 +02:00
|
|
|
self.backLinkText = data.backLinkText ?? parent.backLinkText
|
2022-08-26 17:40:51 +02:00
|
|
|
self.parentBackLinkText = parent.backLinkText
|
2022-08-19 18:05:06 +02:00
|
|
|
self.placeholderTitle = data.placeholderTitle ?? parent.placeholderTitle
|
|
|
|
self.placeholderText = data.placeholderText ?? parent.placeholderText
|
|
|
|
self.titleSuffix = data.titleSuffix
|
|
|
|
self.thumbnailSuffix = data.thumbnailSuffix
|
|
|
|
self.cornerText = data.cornerText
|
|
|
|
self.externalUrl = data.externalUrl
|
|
|
|
|
|
|
|
guard isComplete else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: Thumbnails
|
|
|
|
|
|
|
|
extension Element {
|
|
|
|
|
|
|
|
static let defaultThumbnailName = "thumbnail.jpg"
|
|
|
|
|
|
|
|
static func localizedThumbnailName(for language: String) -> String {
|
|
|
|
"thumbnail-\(language).jpg"
|
|
|
|
}
|
|
|
|
|
|
|
|
static func findThumbnail(for language: String, in folder: URL) -> String? {
|
|
|
|
let localizedThumbnail = localizedThumbnailName(for: language)
|
|
|
|
let localizedThumbnailUrl = folder.appendingPathComponent(localizedThumbnail)
|
|
|
|
if localizedThumbnailUrl.exists {
|
|
|
|
return localizedThumbnail
|
|
|
|
}
|
|
|
|
let defaultThumbnailUrl = folder.appendingPathComponent(defaultThumbnailName)
|
|
|
|
if defaultThumbnailUrl.exists {
|
|
|
|
return defaultThumbnailName
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|