CHGenerator/Sources/Generator/Content/Element+LocalizedMetadata.swift

230 lines
8.5 KiB
Swift
Raw Normal View History

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.
- Note: If `nil` is specified, then the (localized) thumbnail is used, if available.
2022-08-19 18:05:06 +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
/**
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 {
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"
self.language = log
2022-08-19 18:05:06 +02:00
.required(data.language, name: "language", source: source)
.ifNil(markAsIncomplete) ?? ""
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 ?? ""
self.linkPreviewImage = log
.linkPreviewThumbnail(customFile: data.linkPreviewImage, for: language, in: folder, source: source)
let linkPreviewDescription = data.linkPreviewDescription ?? data.description ?? data.subtitle
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
self.backLinkText = log
2022-08-19 18:05:06 +02:00
.required(data.backLinkText, name: "backLinkText", source: source)
.ifNil(markAsIncomplete) ?? ""
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) ?? ""
self.placeholderText = log
2022-08-19 18:05:06 +02:00
.required(data.placeholderText, name: "placeholderText", source: source)
.ifNil(markAsIncomplete) ?? ""
self.titleSuffix = data.titleSuffix
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
}
}
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
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 ?? ""
self.linkPreviewImage = log
.linkPreviewThumbnail(customFile: data.linkPreviewImage, for: language, in: folder, source: source)
let linkPreviewDescription = data.linkPreviewDescription ?? data.description ?? data.subtitle
self.linkPreviewDescription = log
2022-08-19 18:05:06 +02:00
.required(linkPreviewDescription, name: "linkPreviewDescription", source: source)
.ifNil(markAsIncomplete) ?? ""
self.moreLinkText = log.moreLinkText(data.moreLinkText, parent: parent.moreLinkText, source: source)
self.backLinkText = data.backLinkText ?? data.title ?? ""
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
}
}